圖像腐蝕、膨脹算法

腐蝕運算的含義:每當在目標圖像中找到一個與結構元素相同的子圖像時,就把該子圖像中與結構元素的原點位置對應的那個像素位置標註出來,目標圖像上被標註出來的所有像素組成的集合,即爲腐蝕運算的結果。其實質就是在目標圖像中標出那些與結構元素相同的子圖像的原點位置的像素。


算法描述:

1.獲得源圖像每行像素的寬度

2.創建一幅大小與源圖像相同,所有像素置黑的目標圖像

3.爲防止越界,不處理最左邊、最右邊、最上邊和最下邊的像素,從第2行、第2列開始檢查源圖像中的像素點,先將當前點在目標圖像中的對應像素點置白,如果當前點對應結構元素中爲白色的那些點中有一個不是白色,則將目標圖像中的對應像素點置爲黑。

4.循環3步驟,直至處理完源圖像

5.所得的目標圖像即爲腐蝕結果

編程實現:

結構元素爲3*3的全置白矩陣,輸入圖像爲二值圖像

void corrode(Mat &img,uchar mask[3][3],int m,int n)//img爲源圖像,mask爲結構元素,m,n爲結構元素的大小
{
	int width = img.cols;//源圖像每行像素的寬度
	Mat k(img.size(), img.type(), Scalar::all(0)); //創建一幅大小與源圖像相同,所有像素置黑的目標圖像
	for (int i = 1; i < img.rows-1; i++)
	{
		uchar *data = img.ptr<uchar>(i);
		uchar *k_mask = k.ptr<uchar>(i);
		for (int j = 1; j < img.cols - 1; j++)
		{
			if (*data > 100)
			{
				k_mask[j] = 255;//先將當前點在目標圖像中的對應像素點置白
				for (int ii = 0; ii < m; ii++)
				{
					for (int jj = 0; jj < n; jj++)
					{
						if (mask[ii][jj] == 0)
							continue;
						uchar flag = *(data + (ii - 1)*width + (jj - 1));
						if (flag < 100)
						{
							k_mask[j] = 0;//如果當前點對應結構元素中爲白色的那些點中有一個不是白色,則將目標圖像中的對應像素點置爲黑 o9  
							break;

						}
					}
				}
			}
			data++;
		}
	}
	img = k;
}
int main()
{
	uchar mask[3][3];
	for (int i = 0; i < 3; i++) 
		for (int j = 0; j < 3; j++)
		{
			mask[i][j] = 255;
		}
	while (1)
	{
		Mat img = imread("5.jpg", 0);
		imshow("顯示1", img);
		threshold(img, img, 240, 255, 0);
		imshow("源圖像", img);
		corrode(img,mask,3,3);
		imshow("腐蝕效果", img);
		waitKey(10);
	}
    return 0;
}


效果:


膨脹運算的含義:先對結構元素B做關於其原點的反射得到反射集合B^,然後在目標圖像X上將B^平移x,則那些B^平移後與目標圖像X至少有一個非零公共元素相交時,對應的原點位置所組成的集合就是膨脹運算的結果。


算法描述:

1.獲得源圖像每行像素的寬度

2.創建一幅大小與源圖像相同,所有像素置黑的目標圖像

3.爲防止越界,不處理最左邊、最右邊、最上邊和最下邊的像素,從第2行、第2列開始檢查源圖像中的像素點,如果當前點對應結構元素中爲白色的那些點中只要有一個點是白色,則將目標圖像中的當前像素點置爲白。

4.循環3步驟,直至處理完源圖像

5.所得的目標圖像即爲膨脹結果

編程實現:

結構元素爲3*3的全置白矩陣,輸入圖像爲二值圖像

void expand(Mat &img, uchar mask[3][3], int m, int n)
{
	int width = img.cols;//源圖像每行像素的寬度
	Mat k(img.size(), img.type(), Scalar::all(0)); //創建一幅大小與源圖像相同,所有像素置黑的目標圖像
	for (int i = 1; i < img.rows - 1; i++)
	{
		uchar *data = img.ptr<uchar>(i);
		uchar *k_mask = k.ptr<uchar>(i);
		for (int j = 1; j < img.cols - 1; j++)
		{
			bool flag = 0;
			for (int ii = 0; ii < m; ii++)
			{
				for (int jj = 0; jj < n; jj++)
				{
					if (*(data + (ii - 1)*width + (jj - 1)) != 0 && mask[ii][jj] != 0)
					{
						*k_mask = 255;
						flag = 1;
						break;
					}
				}
				if (flag == 1) break;
			}
			k_mask++;
			data++;
		}
	}
	img = k;
}


int main()
{
	uchar mask[3][3];
	for (int i = 0; i < 3; i++) 
		for (int j = 0; j < 3; j++)
		{
			mask[i][j] = 255;
		}
	while (1)
	{
		Mat img = imread("5.jpg", 0);
		imshow("顯示1", img);
		threshold(img, img, 240, 255, 0);
		imshow("源圖像", img);
		expand(img,mask,3,3);
		imshow("膨脹效果", img);
		waitKey(10);
	}
    return 0;
}
效果:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章