OpenCV学习之形态学图像处理:开运算、闭运算、形态学梯度、顶帽、黑帽合辑

一、开运算(Opening Operation),其实就是先腐蚀后膨胀的过程,数学表达式

                dst = open(src,element) = dilate(erode(src,element))

开运算可以用来消除小物体、在纤细点处分离物体、平滑较大物体的边界同时并不明显改变其面积。


二、闭运算(Closing Operation)

先膨胀后腐蚀的过程称为闭运算,其数学表达式如下:

                dst = close(src,element) = erode(dilate(src,element))

闭运算能够排除小型黑洞(黑色区域)


三、形态学梯度(MorphologicalGradient)

形态学梯度为膨胀图与腐蚀图之差,数学表达式如下:

            dst = morph_grad(src,element) = dilate(src,element) - erode(src,element)

对二值图像进行这一操作可以将团块(blob)的边缘突出出来。我们可以用形态学梯度来保留

物体的边缘轮廓。


四、顶帽(Top Hat)

顶帽运算(Top Hat)又被称为“礼貌运算”。为原图像与上文刚刚介绍的“开运算”的结果图之差,

数学表达式如下:

                dst = tophat(src,element) = src - open(src,element)

因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,

得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

顶帽运算往往用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景时候,而小物体比较

有规律的情况下,可以使用顶帽运算进行背景提取。


五、黑帽(Black Hat)

黑帽运算为闭运算的结果图与原图像之差。数学表达式为:

            dst = blackhat(src,element) = close(src,element) -src

黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,这一操作和选择的核大小相关。

所以,黑帽运算用来分离比邻近点暗一下的斑块。


六、高级的形态学变换函数morphologyEx()函数

morphologyEx()函数,利用基本的膨胀和腐蚀技术,来执行更加高级的形态学变换,

比如开环运算、形态学梯度,顶帽运算和黑帽运算等。下面为morphologyEx()函数原型

void cv::morphologyEx( InputArray src, OutputArray dst, int op, InputArray kernel, Pointanchor = Point(-1,-1),

    int iterations = 1, int borderType = BORDER_CONSTANT, constScalar& borderValue = 

     morphologyDefaultBorderValue);

第一个参数,InputArray类型的src,输入图像,即原图像,填Mat类的对象即可。

第二个参数,OutputArray类型的dst,函数的输出对象。

第三个参数,int类型的op(operation),表示形态学运算的类型,可以是如下之一的标识符:

        MORPH_OPEN - 开运算 - CV_MOP_OPEN

        MORPH_CLOSE - 闭运算 - CV_MOP_CLOSE

        MORPH_GRADIENT - 形态学梯度 - CV_MOR_GRADIENT

        MORPH_TOPHAT - 顶帽运算 - CV_MOP_TOPHAT

        MORPH_BLACKHAT - 黑帽运算 - CV_MOP_BLACKHAT

第四个参数,InputArray类型的kernel,形态学运算内核。若为NULL时,表示的是使用参考点位于

中心3x3的核。我们一般使用函数getStructuringElement配合这参数的使用。getStructuringElement

函数会返回指定形状和尺寸的结构元素(内核矩阵)。


getStructingElement()函数的

第一个参数表示内核的形状,我们可以选择如下三种形状之一:

        矩形:MORPH_RECT

        交叉形:MORPH_CROSS

        椭圆形:MORPH_ELLIPSE

第二个参数和第三个参数分别是内核的尺寸以及锚点的位置。

我们一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获取getStructingElement函数的

返回值。对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心。需要注意,十字形的element形状

唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。

实例:

int g_nStructElementSize = 3; // 结构元素(内核矩阵)的尺寸

// 获取自定义核

Mat element = getStructingElement(MORPH_RECT,

   Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),

   Point(g_nStructElementSize, g_nStructElementSize));

调用这样之后,我们便可以在接下来调用erode,dilate或者morphogyEx函数时,

kernel参数填保存getStructingElement返回值的Mat类型变量。对于我们上面的示例,就是填element变量。

第五个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。

第六个参数,int类型的iterations,迭代使用函数的次数,默认值为1

第七个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。它有默认值BORDER_CONSTANT.

第八个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValu,一般                     我们不用管。


  1. // 闭运算操作实例:
  2. int main( )
  3. {
  4. //载入原始图
  5. Mat image = imread( "1.jpg"); //工程目录下应该有一张名为1.jpg的素材图
  6. //创建窗口
  7. namedWindow( "【原始图】闭运算");
  8. namedWindow( "【效果图】闭运算");
  9. //显示原始图
  10. imshow( "【原始图】闭运算", image);
  11. //定义核
  12. Mat element = getStructuringElement(MORPH_RECT, Size( 15, 15));
  13. //进行形态学操作
  14. morphologyEx(image,image, MORPH_CLOSE, element);
  15. //显示效果图
  16. imshow( "【效果图】闭运算", image);
  17. waitKey( 0);
  18. return 0;
  19. }








猜你喜欢

转载自blog.csdn.net/xueluowutong/article/details/80994795