一、开运算(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,一般 我们不用管。