膨胀与腐蚀能实现的功能:消除噪声、分割(isolate)出独立的图像元素,在图像中连接(join)相邻的元素、寻找图像中的明显的极大值区域或极小值区域、求出图像的梯度。
注意:腐蚀和膨胀是对白色部分(高亮部分)而言的。膨胀是图像中的高亮部分进行膨胀,效果图拥有比原图更大的高亮区域。腐蚀就是原图中的高亮部分被腐蚀,效果图拥有比原图更小的高亮区域。
1、膨胀——dilate函数
函数原型:void dilate( InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() );
第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像通道的数量可以是任意的,但图像深度应为CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
第三个参数,InputArray类型的kernel,膨胀操作的核。若为NULL时,表示的是使用参考点位于中心3x3的核。{
我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。
获取自定义核操作: Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1), Point( g_nStructElementSize, g_nStructElementSize ));
其中,getStructuringElement函数的第一个参数表示内核的形状,我们可以选择如下三种形状之一:矩形: MORPH_RECT交叉形: MORPH_CROSS椭圆形: MORPH_ELLIPSE
而getStructuringElement函数的第二和第三个参数分别是内核的尺寸以及锚点的位置。我们一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心。且需要注意,十字形的element形状唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。}
第四个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。
第五个参数,int类型的iterations,迭代使用erode()函数的次数,默认值为1。
第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
第七个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
//载入原图
Mat image = imread("D://RM//OpenCv的学习//形态学处理//图像的膨胀//11.jpg");
//显示原图
imshow("原图", image);
//获取自定义核
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat dst;
//进行膨胀操作
dilate(image,dst,element);
//显示效果图
imshow("膨胀操作",dst);
waitKey(0);
return 0;
}
代码结果:
2、腐蚀——erode函数
函数原型void erode( InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() );
函数参数介绍与上面膨胀的介绍类似。
用法:
//载入原图
Mat img = imread("RM.jpg");
//获取自定义核
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat dst;
//进行腐蚀操作
erode(img,dst, element);
腐蚀例子:
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat img;
img = imread("D://RM//OpenCv的学习//形态学处理//图像的膨胀//11.jpg");
imshow("原图", img);
//获取自定义核
Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
Mat dst;
//腐蚀操作
erode(img, dst, element);
imshow("腐蚀操作",dst);
waitKey(0);
return 0;
}
3、开闭运算
1)、开运算
定义:
就是先腐蚀后膨胀的过程
作用:
1、开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不边。
2、开运算是一个基于几何运算的滤波器。
3、结构元素大小的不同将导致滤波效果的不同。
4、不同的结构元素的选择导致了不同的分割,即提取出不同的特征。
eg:
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat img1;
img1 = imread("D://RM//OpenCv的学习//形态学处理//开运算//11.jpg");
Mat element;
element = getStructuringElement(MORPH_RECT, Size(5, 5));
Mat dst1;
morphologyEx(img1, dst1, MORPH_OPEN, element);
imshow("开运算",dst1);
waitKey(0);
return 0;
}
2).闭运算
定义:闭运算是先膨胀后腐蚀的过程。
作用:闭运算能够排除小型黑洞(黑色区域)。
eg:
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat img1;
img1 = imread("D://RM//OpenCv的学习//形态学处理//闭运算//11.jpg");
Mat element;
element = getStructuringElement(MORPH_RECT, Size(5, 5));
Mat dst1;
morphologyEx(img1, dst1, MORPH_CLOSE, element);
imshow("闭运算", dst1);
waitKey(0);
return 0;
}
开闭运算总结:1.找核、2、运用函数。