OpenCV实现膨胀与腐蚀

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Coco825211943/article/details/76686897

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

 
 

 
 
 
 
 
 
 

猜你喜欢

转载自blog.csdn.net/Coco825211943/article/details/76686897