OpenCV實現膨脹與腐蝕

OpenCV實現膨脹與腐蝕  

     

       形態學(morphlogy)就是基於形狀的一系列圖像處理操作,而膨脹與腐蝕是兩種最基礎的形態學操作。開運算、閉運算、形態學梯度、頂帽、黑帽都是基於膨脹與腐蝕來實現的。

      膨脹與腐蝕主要可以用來

              1.消除噪音

              2.分割出獨立的圖像元素,在圖像中連接相鄰的元素

              3.找出圖像中的明顯極大值區域或者極小值區域

              4.找出圖像的梯度


原理說明:二者均對於高亮地區而言(以二值圖像爲例)

膨脹(dilate):求局部最大值

核與圖像卷積,即計算核覆蓋的區域的像素的最大值,並把這個最大值賦給參考點的指定像素。

原理圖:



數學公式:

                     


函數調用:

void cv::dilate( InputArray src, OutputArray dst, InputArray kernel,
                 Point anchor, int iterations,
                 int borderType, const Scalar& borderValue )
{
    morphOp( MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}



腐蝕(erode):求局部最小值

核與圖像卷積,即計算核覆蓋的區域的像素的最小值,並把這個最小值賦給參考點的指定像素。


原理圖:



數學公式:

                                     


函數調用:

void cv::erode( InputArray src, OutputArray dst, InputArray kernel,
                Point anchor, int iterations,
                int borderType, const Scalar& borderValue )
{
    morphOp( MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}


函數調用:在這裏,只實現膨脹,腐蝕原理類似。
代碼:

void method_one(InputArray src, OutputArray dst, int d)
{
	int radius = d / 2;
	d = radius * 2 + 1;
	int row = src.rows();
	int col = src.cols();


	dst.create(row, col, src.type());
	src.copyTo(dst);//拷貝


	Mat _src = src.getMat();
	Mat _dst = dst.getMat();




	for (int i = 0; i < row; ++i)
	{
		for (int j = 0; j < col;++j)
		{
			if (_src.data[i*col+ j] == 255)//如果當前的像素是255,那麼在r*r的範圍內都應輸出255
			{//要考慮邊界的情況
				int position_start_x = 0 > j - radius ? 0 : j - radius;
				int position_start_y = 0 > i - radius ? 0 : i - radius;
				int position_end_x = col-1 < j + radius ? col - 1: j + radius;
				int position_end_y = row-1 < i + radius ? row - 1: i + radius;


				for (int m = position_start_y; m <= position_end_y; ++m)
				{
					for (int n = position_start_x; n <= position_end_x; ++n)
					{
						_dst.data[m*col + n] = 255;
					}
				}
			}
		}
	}


}


int main()
{
	Mat srcimage = imread("C:\\Users\\l\\Desktop\\2.jpg");


	Mat gray;
	gray.create(srcimage.rows, srcimage.cols, CV_8UC1);
	cvtColor(srcimage,gray,CV_BGR2GRAY);


	Mat binary;
	binary.create(srcimage.rows, srcimage.cols, CV_8UC1);


	for (int i = 0; i < gray.cols*gray.rows*gray.channels();i++)
	{
		if (gray.data[i] < 128)
			binary.data[i] = 0;
		else
			binary.data[i] = 255;
	}


	imshow("原始圖", binary);


	Mat dilateimage(binary.cols,binary.rows,CV_8UC1);//存儲膨脹後的圖像
	Mat element;
	element = getStructuringElement(MORPH_RECT, Size(3, 3));


	double time = static_cast<double>(getTickCount());
	dilate(binary,dilateimage,element,cv::Point(-1,-1),1);
	time = ((double)getTickCount() - time) / getTickFrequency();
	cout << "Opencv自帶函數所用時間" << time <<"秒"<< endl;
    imshow("結果圖", dilateimage);


	Mat result1;
	double time1 = static_cast<double>(getTickCount());
	method_one(binary, result1, 3);
	time = ((double)getTickCount() - time) / getTickFrequency();
	cout << "方法一所用時間" << time << "秒" << endl;
	imshow("方法一的結果圖", result1);


	waitKey(0);
	return 0;
}


結果圖:








其他形態學濾波的應用:


開運算(Opening Operation):先腐蝕後膨脹

        dst = open(src,element)=dilate(erode(src,element));


閉運算(Closing Operation):先膨脹後腐蝕
dst = close(src,element) = erode(dilate(src,element));


形態學梯度(Morphological Grodient):膨脹圖與腐蝕圖只差
dst = morph_grad(src,element) = dilate(src,element)-erode(src.element);


頂帽(Top Hat):原圖像與開運算的結果圖之差
dst = tophat(src,element) = src-open(src,element);


黑帽(Black Hat):閉運算的結果與原圖像之差
dst = blackhat(src,element) = close(src,element)-src;


參考鏈接:
http://www.cnblogs.com/hrlnw/p/5044402.html
http://www.cnblogs.com/slysky/archive/2011/10/16/2214015.html






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