【OpenCv】形态学操作

理论:

形态学操作:腐蚀、膨胀、开、闭,形态学梯度,顶帽,其中膨胀与腐蚀是图像处理中最常用的形态学操作手段。

膨胀:跟卷积操作类似,假设有图像A和结构元素B,结构元素B在图像A上移动,其中B定义其中心为锚点,计算B覆盖下的A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。(注:是用结构B覆盖下的最大像素值来代替锚点

效果如下:(背景区域膨胀,图像内容i变细)

                                                                             

腐蚀:跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下的图像的像素值。(注:是用结构B覆盖下的最小像素值来代替锚点

效果如下:(背景区域腐蚀,图像内容i变粗)

                                                                              

开操作:先膨胀后腐蚀,可以去掉小对象。(结合上面两个图,我是这样记忆的,从门里照射一束光后形成一个光影,先关门-腐蚀操作光影变小,再开门-膨胀操作光影变大,最后的动作是开门所以记为开操作)。

效果如下:

                                                                           

闭操作:先腐蚀后膨胀,可以填充小洞。(记忆方法和开操作一样)。

效果图如下:

                                                                          

形态学梯度:又称基本梯度,膨胀减去腐蚀,其他的还有内部梯度和方向梯度。

效果图如下:

                                                                        

顶帽:原图像与开操作之间的差值图像。

效果图如下:

                                                                               

黑帽:闭操作与原图像的差值图像。

效果图如下:

                                                                                 

 API

 第一步先定义核(模板)kernel=getStructuringElement(int shape,size ksize, point anchor)-第一个参数定义核的形状(MORPH_RECT矩形、MORPH_CROSS圆、MORPH_ELLIPSE椭圆)第二个参数表示大小,第三个参数定义锚点默认为point(-1,-1)中心点

第二步:

膨胀:dilate(src,dst,kernel);腐蚀:erode(src,dst,kernel);src-输入图像,dst-输出图像,kernel-核

形态学操作:morphologyEx(src,dst,CV_MOP_BLACKHAT,kernel,iteration),第一个参数输入图像,第二个参数输出图像,第三个参数形态学操作类型包括(CV_MOP_CLOSE闭操作,CV_MOP_OPEN开操作,CV_MOP_GRADIENT基本梯度操作,CV_MOP_TOPHAT顶帽操作,CV_MOP_BLACKHAT黑帽操作),第四个参数核,第五个参数跌打次数默认为1

程序示例

膨胀与腐蚀

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace cv;

Mat src, dst;
char OUTPUT_WIN[] = "output image";
int element_size = 3;
int max_size = 21;
void CallBack_Demo(int, void*);
int main(int argc, char** argv) {
	
	src = imread("D:/test.png");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);
	createTrackbar("Element Size :", OUTPUT_WIN, &element_size, max_size, CallBack_Demo);//拖动滑条,第一个参数滑条的名称,第二个参数作用的窗口名,第三个参数返回变量的地址,第四个参数滑条的最大值,第五个参数调用函数的名称,第六个参数默认
	CallBack_Demo(0, 0);

	waitKey(0);
	return 0;
}

void CallBack_Demo(int, void*) {
	int s = element_size * 2 + 1;
	Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));
	// dilate(src, dst, structureElement, Point(-1, -1), 1);//膨胀
	erode(src, dst, structureElement);//腐蚀
	imshow(OUTPUT_WIN, dst);
	return;
}

膨胀的效果图

 

 腐蚀的效果图

形态学操作

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("D:/test.png");
	if (!src.data) {
		printf("could not load image...\n");
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);
	char output_title[] = "morphology demo";
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);

	Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1));
	morphologyEx(src, dst, CV_MOP_BLACKHAT, kernel);//CV_MOP_CLOSE闭操作,CV_MOP_OPEN开操作,CV_MOP_GRADIENT基本梯度操作,CV_MOP_TOPHAT顶帽操作,CV_MOP_BLACKHAT黑帽操作
	imshow(output_title, dst);

	waitKey(0);
	return 0;
}

黑帽操作

 

顶帽操作

开操作

闭操作

基本梯度操作

 

当然以上操作都可以更改kernel的结构如下:

// 水平结构元素
	Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));
	// 垂直结构元素
	Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));
	// 矩形结构
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));

 直接替换API中的kernel就可以实现,有兴趣的可以试试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值