OpenCV的膨胀和腐蚀

在OpenCV中,膨胀和腐蚀是基本的形态学操作,膨胀是使用像素邻域内的局部极大运算来膨胀一张图片,腐蚀是使用像素邻域内的局部极小运算来腐蚀一张图片,二者是一对相反的操作,但是都是对图像中的白色部分(高亮部分)而言的,膨胀用dilate()函数,腐蚀用erode()函数,函数原型分别如下:

void dilate( InputArray src, OutputArray dst, InputArray kernel,
                          Point anchor = Point(-1,-1), int iterations = 1,
                          int borderType = BORDER_CONSTANT,
                          const Scalar& borderValue = morphologyDefaultBorderValue() );
void erode( InputArray src, OutputArray dst, InputArray kernel,
                         Point anchor = Point(-1,-1), int iterations = 1,
                         int borderType = BORDER_CONSTANT,
                         const Scalar& borderValue = morphologyDefaultBorderValue() );

一、实例代码:

#include 
//#include 
#include 
#include 
#include 
#define WINDOWNAME "【效果图】"
using namespace std;
using namespace cv;

//------------------------【全局变量声明】
Mat g_srcImage, g_dstImage;      //原始图和效果图
int g_nTrackbarNumber = 0;       //0表示腐蚀erode,1表示膨胀dilate,初始值设为0表示用腐蚀
int g_nStructElementSize = 3;    //结构元素(内核矩阵)的尺寸


//-------------------------【全局函数声明】
void Process();                           //膨胀和腐蚀的处理函数
void on_TrackbarNumChange(int, void*);    //回调函数
void on_ElementSizeChange(int, void*);    //回调函数


int main()
{
	//改变console字体颜色
	//system("color 2F");

	//载入原图
	g_srcImage = imread("F:\\TuPian\\littlecat.jpg");
	if (g_srcImage.data == NULL)
	{
		cout << "读取srcImage失败!" << endl;
	}

	//显示原始图
	const char* pName1 = "原始图";
	namedWindow(pName1);
	imshow(pName1, g_srcImage);

	// 进行初次腐蚀操作并显示效果图
	const char* Pname = "图2";
	namedWindow(Pname);
	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(Pname, g_dstImage);

	namedWindow(WINDOWNAME);
	//显示的图像是根据图像的名称来显示的
	//只是创建了带有窗口名的一个窗口,里面并没有任何图像内容
	//创建轨迹条
	//在创建的窗体中创建一个滑动条控件

	createTrackbar("腐蚀/膨胀", WINDOWNAME, &g_nTrackbarNumber, 1, on_TrackbarNumChange);  //第三个参数是滑块的初始位置,第4个参数是最大值
	createTrackbar("内核尺寸", WINDOWNAME, &g_nStructElementSize, 21, on_ElementSizeChange);
	//on_TrackbarNumChange(g_nTrackbarNumber, 0);          //【回调函数初始化】
	//on_ElementSizeChange(g_nStructElementSize, 0);       //【回调函数初始化】
	//需要进行回调函数初始化,不进行初始化就没有初始图像显示
	
	//按任意键退出
	waitKey(0);

	return 0;
	//std::cout << "Hello World!\n"; 
}


//-----------------------------【Process()函数】
//描述:进行自定义的腐蚀和膨胀操作
void Process()
{
	//获取自定义内核
	Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize));
	//进行膨胀或腐蚀操作
	if (g_nTrackbarNumber == 0)
	{
		erode(g_srcImage, g_dstImage, element);
	}
	else
	{
		dilate(g_srcImage, g_dstImage, element);
	}
	
	//显示效果图
	imshow(WINDOWNAME, g_dstImage);
}

//-----------------------------【on_TrackbarNumChange()函数】
//描述:腐蚀和膨胀之间切换开关的回调函数
void on_TrackbarNumChange(int, void*)
{
	//腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
	Process();
}

//-----------------------------【on_ElementSizeChange()函数】
//描述:腐蚀和膨胀操作内核改变时的回调函数
void on_ElementSizeChange(int, void*)
{
	//内核尺寸已经改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
	Process();
}

二、结果:

 OpenCV的膨胀和腐蚀_第1张图片

调整第3幅图上的滑块,结果如下图所示:

OpenCV的膨胀和腐蚀_第2张图片

第3幅图之所以最开始没有显示出图像,是因为没有进行函数的回调,代码中的这两行注释掉了,

//on_TrackbarNumChange(g_nTrackbarNumber, 0);          //【回调函数初始化】
//on_ElementSizeChange(g_nStructElementSize, 0);       //【回调函数初始化】

如果不注释掉这两行,则第3幅图最开始就会显示出来。

 OpenCV的膨胀和腐蚀_第3张图片

 

参考: 《OpenCV3编程入门》毛星云、冷雪飞等编著,电子工业出版社,2018年11月第19次印刷,p187-198。

 

你可能感兴趣的:(OpenCV)