Opencv学习笔记(四)形态学运算

大纲

  • 一.腐蚀与膨胀
  • 二、开运算与闭运算
  • 三、顶帽与黑帽
  • 四、形态学梯度
  • 五、总函数介绍

一.腐蚀与膨胀

腐蚀和膨胀是形态学运算中的基本操作,也是后续要介绍的运算的基础,首先腐蚀与膨胀从字面意义上来理解,指的是对于图片中灰度较高的部分(多通道独立处理)扩张或者收缩,即经过操作后亮域变少\多。实现方法是通过窗函数在原图上滑动,将卷积核(可以是任意大小、形状)范围内最大值(膨胀)或者最小值(腐蚀)作为锚点的像素值
Opencv的膨胀函数原型如下:

dilate( InputArray src, OutputArray dst, InputArray kernel,
Point anchor = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() );

第一、二个参数为输入输出图片,二者应该具有相同的格式,且深度应该为CV_8U、CV_16U、CV_16S、CV_32F、CV_64F之一;
第三个参数为卷积核,如果输入NULL的话则默认使用3×3矩形卷积核,通常情况下会搭配getStructuringElement()来获得这一参数;

Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
第一个参数为卷积核的形状,有MORPH_RECT、MORPH_CROSS、MORPH_ELLIPSE三种选项;
第二个参数为卷积核的大小;
第三个参数为锚点的位置,默认值(-1,-1)即在卷积核中心;

第四个参数也为卷积核锚点;(尚不明确和卷积核锚点冲突有什么后果)
第五个参数为迭代使用dilate()函数的次数,默认为1;
第六个参数为边界填充方式;
第七个参数用于当第六个参数设定为常数时填充的边界值,默认值morphologyDefaultBorderValue();
腐蚀函数原型

erode( InputArray src, OutputArray dst, InputArray kernel,
Point anchor = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() );

参数与膨胀函数参数大同小异,不再赘述。

二、开运算与闭运算

开运算和闭运算是基于腐蚀和膨胀进行的,前者是先腐蚀后膨胀,后者是先膨胀后腐蚀。下面将用实例来介绍二者的差异与作用:
对于开运算而言,先腐蚀后膨胀可以用来消除小物体,在纤细点处分离物体,并且在平滑较大物体边界时不改变其面积。通俗的将就是保证图像不发生较大变化的同时,使得内部藕断丝连的部分彻底分开,外部突出的部分直接平滑掉,具体过程参见下图:
Opencv学习笔记(四)形态学运算_第1张图片
而对于闭运算而言,是先膨胀后腐蚀,能够排除掉小型的黑洞,即能够将藕断丝连的部分完全弥合起来,具体过程参见下图:
Opencv学习笔记(四)形态学运算_第2张图片
二者的函数原型将在后续统一介绍。

三、顶帽与黑帽

顶帽是原图像与开运算之后图像的差,因为开运算是放大了裂缝区域、局部低亮度的区域,也就是让明亮区域中穿插的暗部变大了,减去开运算得到图像后就突出了因为暗部扩大而消失的小块亮区域,也就是比原图轮廓周围区域更明亮的区域。见下图变化:
Opencv学习笔记(四)形态学运算_第3张图片
顶帽运算之后:
Opencv学习笔记(四)形态学运算_第4张图片
可以看到顶帽运算使得那些不连续的亮区域保留了下来。
黑帽是闭运算之后图像与原图的差值,由于闭运算使得裂缝弥合,将亮区域的面积扩大了,所以减去原图像之后,就留下了这些原来暗区域的裂缝,突出了比原图轮廓周围区域更暗的区域。见下图变化:
原图:
Opencv学习笔记(四)形态学运算_第5张图片
黑帽运算之后:
Opencv学习笔记(四)形态学运算_第6张图片
可以看到黑帽运算将原图亮区域的斑点保留了下来。
两运算的函数原型将在后续介绍。

四、形态学梯度

形态学梯度运算为膨胀图像与腐蚀图像之差,膨胀是对于亮区域的扩张、暗区域的收缩 ;腐蚀是对于亮区域的收缩、暗区域的扩张,二者相减正好就突出了亮、暗区域的边界线,给出了图像的轮廓。
原图:
Opencv学习笔记(四)形态学运算_第7张图片
形态学梯度运算后:
Opencv学习笔记(四)形态学运算_第8张图片

五、总函数介绍

上述所有的形态学运算都可以通过形态学滤波函数 morphologyEx()来实现,原型如下:

morphologyEx( InputArray src, OutputArray dst,int op, 
InputArray kernel,Point anchor = Point(-1,-1), 
int iterations = 1,int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() );

第一、二个参数为输入输出图片,二者应该具有相同的格式,且深度应该为CV_8U、CV_16U、CV_16S、CV_32F、CV_64F之一;
第三个参数为标识符,可选择MORPH_ERODE、MORPH_DILATE、MORPH_OPEN、MORPH_CLOSE、MORPH_TOPHAT、MORPH_BLACKHAT、MORPH_GRADIENT,以实现上述所有形态学运算。
第四个参数为卷积核,如果输入NULL的话则默认使用3×3矩形卷积核,通常情况下会搭配getStructuringElement()来获得这一参数;

Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
第一个参数为卷积核的形状,有MORPH_RECT、MORPH_CROSS、MORPH_ELLIPSE三种选项;
第二个参数为卷积核的大小;
第三个参数为锚点的位置,默认值(-1,-1)即在卷积核中心;

第五个参数也为卷积核锚点;(尚不明确和卷积核锚点冲突有什么后果)
第六个参数为迭代使用dilate()函数的次数,默认为1;
第七个参数为边界填充方式;
第八个参数用于当第六个参数设定为常数时填充的边界值,默认值morphologyDefaultBorderValue();

参考文献
顶帽和黑帽
形态学应用——开运算和闭运算

你可能感兴趣的:(opencv,计算机视觉,opencv)