OpenCV学习心得——基础篇——滤波与卷积——图像形态学与核的卷积

OpenCV学习心得——基础篇——滤波与卷积——图像形态学与核的卷积
FOR THE SIGMA
FOR THE GTINDER
FOR THE ROBOMASTER

简介:

这一系列的学习心得第一轮将参考《学习OpenCV3》一书

操作系统版本:Ubuntu16.04(在这里博主在Linux下进行运行的)
http://www.ubuntu.org.cn/download/desktop 桌面版ubuntu16.04 下载

电子版书籍下载地址
暂无资源

内容:

OpenCV提供了一种高效且易用的图像形态学变换接口。其中有很多形态学方法,但基本上所有的形态学操作都基于两种原始操作——膨胀与腐蚀。

膨胀与腐蚀
膨胀和腐蚀是最基本的形态学变换,可用于消除噪声、元素分割和连接、寻找图像中明显的极大值区域或极小值区域等。基于这两种操作,可以实现更复杂的形态学操作,用来定位强度峰值或孔洞、另一种形式的图像梯度等。

==膨胀(dilate)==是一种卷积操作,求局部最大值,它将目标像素的值替换为卷积核覆盖区域的局部最大值,扩张了明亮区域,填充凹面。此卷积核是一个非线性核,是一个四边形或圆形的实心核,其锚点在中心。

==腐蚀(erode)==是与之相反的操作,腐蚀操作计算的是核覆盖范围内的局部最小值缩减了明亮区,消除凸起。

总的来说膨胀就是扩展了明亮区域,填充凹面;腐蚀缩减了明亮区域,消除凸起。

void cv::dilate(  //膨胀
	cv::InputArray src,
	cv::OutputArray dst,
	cv::inputArray element,  //膨胀操作的核,当为NULL时,使用3*3的核
	cv::Point	anchor	=	cv::Point(-1,-1),  //锚的位置,其默认值(-1,,1)
	int	iterations = 1, 	//迭代使用erode函数的次数,默认为1
	int	borderType = cv::BORDER_CONSTANT  //用于推断图像外部像素的某种边界模式
	const cv::Scalar&	borderValue = cv::morphologyDefaultBorderValue( )
	);
void cv::erode(  //腐蚀
	cv::InputArray src,
	cv::OutputArray dst,
	cv::inputArray element,  //膨胀操作的核,当为NULL时,使用3*3的核
	cv::Point	anchor	=	cv::Point(-1,-1),  //锚的位置,其默认值(-1,,1)
	int	iterations = 1, 	//迭代使用erode函数的次数,默认为1
	int	borderType = cv::BORDER_CONSTANT  //用于推断图像外部像素的某种边界模式
	const cv::Scalar&	borderValue = cv::morphologyDefaultBorderValue( )
	);

通用形态学函数
又被称为高级形态学变换,当处理的对象是二值图像时,像素只能是开(>0)或关(=0)的图像掩膜时,基本的腐蚀和膨胀操作就够用了。需要对灰度图或者彩色图进行处理时,一些其他操作就非常有用了,这些操作可以通过cv::morphologyEx()实现。

void cv::morphologyEx(
	cv::InputArray	src,
	cv::OutputArray	dst,
	int op,  //指定函数进行的操作类型
	cv::InputArray	element,
	cv::Point	anchor	= cv::Point(-1,-1),
	int	iterations = 1,
	int	borderType = cv::BORDER_DEFAULT

op表

操作值形态学操作是否需要临时图像
cv::MOP_OPEN开操作
cv::MOP_CLOSE闭操作
cv::MOP_GRADIENT形态学梯度总是需要
cv::MOP_TOPHAT顶帽操作就地调用需要src=dist
cv::MOP_BLACKHAT底帽操作就地调用需要src=dist

开运算和闭运算
开运算先将图像进行腐蚀,然后对腐蚀的结果进行膨胀。开操作常用语对二值图像中的区域进行计算。
dst = open(src,element) = dilate(erode(src,element) )

闭运算想将图像进行膨胀,然后对膨胀的结果进行腐蚀。闭操作用于复杂连通分支算法中减少无用或噪声驱动的片段。
dst=clese(src,element) = erode(dilate(src,element) )

对于连通分支,通常先进行腐蚀或闭操作消除噪声,然后通过开操作连接相互靠近的大型区域。
对于一幅非布尔型图像进行形态学操作时,闭操作最明显的效果是消除值小于邻域内的点的孤立异常,而开操作消除的是大于邻域内点的孤立异常值。
参考:https://blog.csdn.net/hanshanbuleng/article/details/80657148

形态学梯度
在这里插入图片描述梯度操作的结果(扩张亮域)减腐蚀操作的结果(缩减亮域)产生了原图像中的目标边缘。对于灰度图像,其结果就是计算明暗变换的趋势。形态学梯度通常用于显示明亮区域的边界,然后便可以将他们看作目标或者目标的部分。用扩张的图像减去了收缩的图像便得到完整的边界。与计算梯度不同,它并不会关注某个物体的周围。

顶帽与黑帽
在这里插入图片描述
顶帽用于显示与其邻近相比更亮的部分;黑帽用于显示与其邻近相比更暗的部分。
参考:https://blog.csdn.net/qq_36387683/article/details/80489631

实例:

#include <opencv2/opencv.hpp>


int main()
{
	cv::namedWindow("image", cv::WINDOW_NORMAL);
	cv::namedWindow("erosion", cv::WINDOW_NORMAL); 	//腐蚀
	cv::namedWindow("dilation", cv::WINDOW_NORMAL); //膨胀
	cv::namedWindow("opening", cv::WINDOW_NORMAL);  //开运算
	cv::namedWindow("closing", cv::WINDOW_NORMAL);	//闭运算
	cv::namedWindow("gradient", cv::WINDOW_NORMAL); //形态学梯度
	cv::namedWindow("topHat", cv::WINDOW_NORMAL); //顶帽
	cv::namedWindow("blackHat", cv::WINDOW_NORMAL); //黑帽

	cv::Mat img = cv::imread("pic.jpg");

	cv::Mat erosion, dilation, opening, closing, gradient, topHat, blackHat;
	cv::erode(img, erosion, cv::Mat());
	cv::dilate(img, dilation, cv::Mat());
	cv::morphologyEx(img, opening, cv::MORPH_OPEN, cv::Mat());
	cv::morphologyEx(img, closing, cv::MORPH_CLOSE, cv::Mat());
	cv::morphologyEx(img, gradient, cv::MORPH_GRADIENT, cv::Mat());
	cv::morphologyEx(img, topHat, cv::MORPH_TOPHAT, cv::Mat());
	cv::morphologyEx(img, blackHat, cv::MORPH_BLACKHAT, cv::Mat());

	cv::imshow("image", img);
	cv::imshow("erosion", erosion);
	cv::imshow("dilation", dilation);
	cv::imshow("opening", opening);
	cv::imshow("closing", closing);
	cv::imshow("gradient", gradient);
	cv::imshow("topHat", topHat);
	cv::imshow("blackHat", blackHat);
	cv::waitKey(0);
	cv::destroyAllWindows();
    return 0;
}

自定义核
Opencv可以让你创建自己的核,在形态学上,核常常被称为“构造元素”,而使用cv::getStructuringElement()函数便可以自定义一个核。

cv::Mat cv::getStructuringElement(
	int shape,   //构造元素的基本形状
	cv::size ksize,  //元素大小
	cv::Point anchor = cv::Point(-1,-1)  //锚点位置。
	);

元素形状shape表

形状值元素
cv::MORPH_RECT矩形
cv::MORPH_ELLIPSE椭圆形
cv::MORPH_CROSS交叉

==cv::filter2D()==进行卷积

void cv::filter2D(
	InputArray src,
	OutputArray dst, 
	int ddepth, 
	InputArray kernel, 
	cv::Point anchor=cv::Point(-1, -1), 
	double delta=0, 
	int borderType=cv::BORDER_DEFAULT
	);

注:如果定义了锚点的位置,那么核的大小可以是偶数,否则必须是奇数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值