一、理论与概念讲解 — 从现象到本质
一些基本符号和关系:图像的膨胀与腐蚀–确认这个大牛的才是正确的
-
结构元素:二维结构元素可以理解为二维矩阵,矩阵的元素值为0或1;通常结构元素小于要处理的图像。设有两幅图象B,X。若X是被处理的对象,而B是用来处理X的,则称B为结构元素(structure element),又被形象地称做刷子。结构元素通常都是一些比较小的图象。(如果没有基础的话,先接受它,慢慢往下阅读,再回头看这个概念)
-
内核:内核是与结构元素有关的概念,可以理解为内核是二维结构元素矩阵中元素值为1的部分。
-
锚点:核可以是任何形状和大小,它拥有一个单独定义出来的参考点,这个点称为锚点。
-
再进行腐蚀和膨胀讲解之前,首先需要注意:腐蚀和膨胀是对白色部分(高亮部分)而言,不是黑色部分。膨胀是对图像中高亮部分进行膨胀,“领域扩张”,效果图拥有比原图更大的高亮区域。腐蚀就是原图中高亮部分被腐蚀,“邻域被蚕食”,效果图拥有比原图更小的高亮区域。
4.1 膨胀
膨胀是求局部最大值的操作,核B与图形进行卷积,计算核B覆盖区域像素点的最大值,并把这个最大值赋值给参考点(锚点),这样会使高亮区域逐渐增加。如下图:
原理图:
膨胀的数学表达式:
膨胀效果图(足球):
4.2 腐蚀
腐蚀是取局部最小值,我们一般会把膨胀和腐蚀对比起来理解和学习。
原理图:
数学表达式:
腐蚀效果图:
二、API函数快速上手
- 形态学膨胀 — dilate函数
使用像素领域局部极大值来膨胀图片。
函数原型:
void dilate(InputArrray src,
OutputArray dst;
InoutArray kernel,
Point anchor=Point(-1,-1),
int iterations=1,
int borederType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue()
)
参数详解:
- src:输入图像,即源图像,Mat类的对象即可。
- dst:输出图像,即目标图像,需要和原图片一样的尺寸和类型。
- kernel:膨胀操作的核。若为NULL时,表示使用参考点位于中心3×3的核。
- anchor:锚的位置,有默认值(-1,-1),表示锚位于中心。
- iterations:迭代使用erode()函数的次数,默认为1.
- borderType:int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
- borderValue:const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的。
- 形态学腐蚀 — erode函数
使用像素领域的局部极小值来腐蚀图片。
函数原型:
void erode( InoutArray src,
OutputArray dst;
InoutArray kernel,
Point anchor=Point(-1,-1),
int iterations=1,
int borderType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue()
)
参数详解:
- src:源图像。
- dst:目标图像
- kernel:腐蚀操作内核。
- anchor:锚的位置。
- iterations:迭代次数。
- borderType:同上 。
- borderValue:同上。
一般使用前三个即可,后四个保持默认值即可。
我们一般在调用erode以及dilate函数的时候,会配合getStructuringElement函数使用。
/*
Mat getStructuringElement(int shape, Size esize, Point anchor = Point(-1, -1));函数:会返回指定形状和尺寸的结构元素
第一个参数表示内核形状:矩形:MORPH_RECT; 交叉型:MORPH_CROSS; 椭圆形:MORPH_ELLIPSE;
第二个参数:内核的尺寸
第三个参数:锚点的位置,默认为Point(-1,-1),表示位于中心点。
*/
三、实战
#if 1:
#include "opencv2/opencv.hpp"
#include "iostream"
//命名空间
using namespace cv;
using namesapce std;
int main()
{
int flag; //操作选择
cin >> flag;
Mat srcImg = imread("1.jpg"); //1.jpg为放在工程文件下的图片名字,否则加上绝对路径
imshow("[原图]", srcImg);
Mat element = getStructuringElement(MORPH_RECT, Size(3,3), Point(5,5)); // 核
if(flag == 1) // 腐蚀
{
Mat dstImg1;
erode(srcImg, dstImg, element);
imshow("[腐蚀图]", dstImg1);
waitKey();
}
else // 膨胀
{
Mat dstImg2;
dilate(srcImg, dstImg2, element);
imshow("[膨胀图]", dstImg2);
waitKey();
}
return 0;
}
#endif