图像腐蚀与膨胀
结构元素
设有两幅图象B,X。若X是被处理的对象,而B是用来处理X的,则称B为结构元素(structure element),又被形象地称做刷子。结构元素通常都是一些比较小的图象。
腐蚀
把结构元素B平移a后得到Ba,若Ba包含于X,我们记下这个a点,所有满足上述条件的a点组成的集合称做X被B腐蚀(Erosion)的结果。如下图所示。
其中X是被处理的对象,B是结构元素。对于任意一个在阴影部分的点a,Ba 包含于X,所以X被B腐蚀的结果就是那个阴影部分。阴影部分在X的范围之内,且比X小,就象X被剥掉了一层似的。膨胀
膨胀(dilation)可以看做是腐蚀的对偶运算,其定义是:把结构元素B平移a后得到Ba,若Ba击中X,我们记下这个a点。所有满足上述条件的a点组成的集合称做X被B膨胀的结果。如下图所示。
其中X是被处理的对象,B是结构元素,不难知道,对于任意一个在阴影部分的点a,Ba击中X,所以X被B膨胀的结果就是那个阴影部分。阴影部分包括X的所有范围,就象X膨胀了一圈似的。
接下来请看如下图:我们就能了解其具体工作原理了。
图像的膨胀:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace std; using namespace cv; int main( ) { //载入原图 Mat image = imread("C://1.jpg"); //创建窗口 namedWindow("【原图】膨胀操作"); namedWindow("【效果图】膨胀操作"); //显示原图 imshow("【原图】膨胀操作", image); //进行膨胀操作 Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); Mat out; dilate(image, out, element); //显示效果图 imshow("【效果图】膨胀操作", out); waitKey(0); return 0; }图像的腐蚀: 代码如下:
#include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; int main( ) { //载入原图 Mat srcImage = imread("C://1.jpg"); //显示原图 imshow("【原图】腐蚀操作", srcImage); //进行腐蚀操作 Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); Mat dstImage; erode(srcImage, dstImage, element); //显示效果图 imshow("【效果图】腐蚀操作", dstImage); waitKey(0); return 0; }图像的膨胀和腐蚀的综合示例:可以改变滑动条窗口改变内核的大小,0代表腐蚀,1代表膨胀。 代码如下:
#include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace std; using namespace cv; //-----------------------------------【全局变量声明部分】-------------------------------------- // 描述:全局变量声明 //----------------------------------------------------------------------------------------------- Mat g_srcImage, g_dstImage;//原始图和效果图 int g_nTrackbarNumer = 0;//0表示腐蚀erode, 1表示膨胀dilate int g_nStructElementSize = 3; //结构元素(内核矩阵)的尺寸 //-----------------------------------【全局函数声明部分】-------------------------------------- // 描述:全局函数声明 //----------------------------------------------------------------------------------------------- void Process();//膨胀和腐蚀的处理函数 void on_TrackbarNumChange(int, void *);//回调函数 void on_ElementSizeChange(int, void *);//回调函数 //-----------------------------------【main( )函数】-------------------------------------------- // 描述:控制台应用程序的入口函数,我们的程序从这里开始 //----------------------------------------------------------------------------------------------- int main( ) { //载入原图 g_srcImage = imread("C://1.jpg"); if( !g_srcImage.data ) { printf("读取srcImage错误~! \n"); return false; } //显示原始图 namedWindow("【原始图】"); imshow("【原始图】", g_srcImage); //进行初次腐蚀操作并显示效果图 namedWindow("【效果图】"); //获取自定义核 Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize )); erode(g_srcImage, g_dstImage, element); imshow("【效果图】", g_dstImage); //创建轨迹条 createTrackbar("腐蚀/膨胀", "【效果图】", &g_nTrackbarNumer, 1, on_TrackbarNumChange); createTrackbar("内核尺寸", "【效果图】", &g_nStructElementSize, 21, on_ElementSizeChange); //输出一些帮助信息 cout<<endl<<"\t运行成功,请调整滚动条观察图像效果~\n\n" <<"\t按下“q”键时,程序退出。\n"; //轮询获取按键信息,若下q键,程序退出 while(char(waitKey(1)) != 'q') {} return 0; } //-----------------------------【Process( )函数】------------------------------------ // 描述:进行自定义的腐蚀和膨胀操作 //----------------------------------------------------------------------------------------- void Process() { //获取自定义核 Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize )); //进行腐蚀或膨胀操作 if(g_nTrackbarNumer == 0) { erode(g_srcImage, g_dstImage, element); } else { dilate(g_srcImage, g_dstImage, element); } //显示效果图 imshow("【效果图】", g_dstImage); } //-----------------------------【on_TrackbarNumChange( )函数】------------------------------------ // 描述:腐蚀和膨胀之间切换开关的回调函数 //----------------------------------------------------------------------------------------------------- void on_TrackbarNumChange(int, void *) { //腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来 Process(); } //-----------------------------【on_ElementSizeChange( )函数】------------------------------------- // 描述:腐蚀和膨胀操作内核改变时的回调函数 //----------------------------------------------------------------------------------------------------- void on_ElementSizeChange(int, void *) { //内核尺寸已改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来 Process(); }结果实例图: