数学形态学实际上可以理解为一种滤波行为,所以很多地方称它为形态学滤波。有了个这概念,我们就能更好的理解它。我们滤波中用的滤波器(kernel)在这里被称为结构元素,结构元素往往是由一个特殊的形状构成,如:线条、矩形、圆、菱形等。我们把结构元素的中心(Anchor Point)与图像上像素点对齐,然后结构元素覆盖的领域像素就是我们要分析的像素,我们定义一种操作就形成了一种形态学运算。
我们在这里不解释形态学操作的算法原理及它们的意义,有兴趣的可以参见相关数字图像处理方面的教材,或关注本博客,博主打算在OpenCV系列写完后,开始写图像处理方面算法系列的文章。
推荐阅读:
腐蚀运算:erode
src:输入图像,很多场合下我们使用的是二值图像,当然灰度图像也可以。
dst:输出图像,格式和输入图像一致。
kernel:定义的结构元素。
anchor:结构元素的中心,如果是默认参数(-1,-1),程序会自动将其设置为结构元素的中心。
iterations:迭代次数,我们可以选择对图像进行多次形态学运算。
后面两个参数是边界类型,由于要处理领域问题,所以图像需要扩充边界。一般情况下使用默认即可。
膨胀运算:dilate
膨胀跟腐蚀的参数完全一致,就不过多的说明了。这两个形态学操作是最基本的两个操作。
下面要介绍的两个形态学操作,在实际应用中要比上面两个更加广泛,但实际上它们是上面两种操作的一个组合式的操作。
开运算与闭运算
这两个运算都是使用函数morphologyEx来实现的,这个函数的接口如下:
函数的大部分参数都与上面介绍的erode函数参数是一样的,这里面的op是我们要进行的形态学的类型:
MORPH_OPEN:对图像进行开运算。
MORPH_CLOSE:对图像进行闭运算。
下面我们还是以小猫图像为例显示一下对二值图像进行开运算和闭运算后得到的结果。
从图片中我们可以得出结论:
闭运算可以填充图像中的孔洞,连接一些缺口;开运算可以去除图像中一些较小的结构。前提是这些孔洞或碎片要与进行运算的结构元素尺度相当。
其实用形态学来检测边缘的原理非常简单,我们打开源码看它是怎么操作的:
可以看出来,它是对图像先做了一个腐蚀,再做了一次膨胀,然后将两次的结果相减即可。
下面我们来实现用形态学操作来检测角点。
首先我们需要定义几个特殊的结构元素,我们这里都用Mat来定义,并像素式的赋值,你可以选择OpenCV里的getStructElement来更快的实现。
第一个为一个十字型的结构元素,第二个为菱形,第三个是矩形,第四个是一个“X”
型。
然后我们按下面的顺序对一幅图像进行操作,并对最后的结果进行阈值化。
经过上面步骤,我们得到了一张二值图像,显示了图像的一些角点的位置。
为了更形象的说明,我们将上面的这些点在原彩色图像上标出来: