OpenCV学习笔记之七——图像形态学处理(一)


首先感谢@浅墨_毛星云,本篇博文是小武通过学习@浅墨_毛星云的博客以及书籍《opencv3.0编程入门》整理的笔记及疑问心得,小武水平有限,欢迎交流。
@浅墨_毛星云博文:https://blog.csdn.net/poem_qianmo/article/category/1923021

一、形态学概述

数学形态学(Mathematical morphology) 是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值开闭运算、灰值形态学梯度等。

最基本的形态学操作有二种,他们是:膨胀与腐蚀(Dilation与Erosion)。
膨胀与腐蚀能实现多种多样的功能,主要如下:

  • 消除噪声
  • 分割(isolate)出独立的图像元素,在图像中连接(join)相邻的元素。
  • 寻找图像中的明显的极大值区域或极小值区域


1、膨胀——dilate函数
函数原型:
C++: void dilate( InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=https://www.it610.com/article/morphologyDefaultBorderValue() );

参数详解:

  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像通道的数量可以是任意的,但图像深度应为CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,InputArray类型的kernel,膨胀操作的核。若为NULL时,表示的是使用参考点位于中心3x3的核。
我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。
其中,getStructuringElement函数的第一个参数表示内核的形状,我们可以选择如下三种形状之一:
    • 矩形: MORPH_RECT
    • 交叉形: MORPH_CROSS
    • 椭圆形: MORPH_ELLIPSE
而getStructuringElement函数的第二和第三个参数分别是内核的尺寸以及锚点的位置。
我们一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心。且需要注意,十字形的element形状唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。


2、腐蚀——erode函数
函数原型:
C++: void erode( InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=https://www.it610.com/article/morphologyDefaultBorderValue() );

参数解释:
  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,InputArray类型的kernel,腐蚀操作的内核。若为NULL时,表示的是使用参考点位于中心3x3的核。我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。
  • 第四个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于单位(element)的中心,我们一般不用管它。
  • 第五个参数,int类型的iterations,迭代使用erode()函数的次数,默认值为1。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
  • 第七个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。

代码实现:
//添加头文件 #include #include #include #includeusing namespace std; using namespace cv; //参数预定义 int Way_num=0; int struct_size=1; MatImg_in , Img_out; //函数声明 void callback_Way_num(int ,void*); void callback_struct_size(int ,void*); void process(); //主函数 int main () { Img_in=imread("lenna.jpg"); imshow("【原图】",Img_in); namedWindow("【效果图】"); createTrackbar("腐蚀/膨胀","【效果图】",&Way_num, 1 , callback_Way_num); callback_Way_num(Way_num,0); createTrackbar("内核尺寸","【效果图】",&struct_size, 37 , callback_struct_size); callback_struct_size(struct_size,0); waitKey(0); return 0; }//进行自定义的腐蚀和膨胀操作 void process() { Mat element=getStructuringElement(MORPH_RECT,Size(struct_size*2+1,struct_size*2+1),Point(struct_size,struct_size)); //Way_num=0,进行腐蚀操作 if (Way_num==0) erode(Img_in,Img_out,element); else //否则,进行膨胀 dilate(Img_in,Img_out,element); imshow("【效果图】",Img_out); }//腐蚀和膨胀之间切换开关的回调函数 void callback_Way_num(int ,void*) { process(); }//腐蚀和膨胀操作内核改变时的回调函数 void callback_struct_size(int ,void*) { process(); }



效果:


OpenCV学习笔记之七——图像形态学处理(一)
文章图片


OpenCV学习笔记之七——图像形态学处理(一)
文章图片


【OpenCV学习笔记之七——图像形态学处理(一)】

    推荐阅读