图像腐蚀和膨胀

一、概论

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

膨胀与腐蚀是图像的最基本的两种变化,他们能实现的功能包括但不限于:
(1) 、消除噪声
(2) 、分割出图像中独立的元素或者连接图像中的元素
(3) 、寻找图像中明显的极大值区域和极小值区域
(4) 、求出图像的梯度

需要注意的是,腐蚀和膨胀是对高亮部分(白色)来说的,图像进行膨胀操作后,它的高亮区域将变大,图像进行腐蚀操作后,他的高亮区域将变小。

二 、膨胀

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

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

膨胀就是局部最大值操作,其实就是将图像与核做卷积运算的结果。核可以是任何的形状和大小,它有一个参考点(锚点)。那么膨胀是如何操作的呢?图像与核覆盖的区域求最大值,然后将这个最大值赋值给指定的像素,这样就会使得图像中的高亮区域逐渐增长。

膨胀的数学表达式为:

三、腐蚀

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

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

腐蚀和膨胀是相反的操作,膨胀希望高亮区域越来越大,而腐蚀希望高亮区域越来越小,看数学表达式就可以理解这一点:

四、看源码理解

//腐蚀操作函数
void cv::erode( InputArray src, OutputArray dst, InputArray kernel,
                Point anchor, int iterations,
                int borderType, const Scalar& borderValue )
{
    //直接调用,设置标志为MORPH_ERODE
    morphOp( MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}

//膨胀操作函数
void cv::dilate( InputArray src, OutputArray dst, InputArray kernel,
                 Point anchor, int iterations,
                 int borderType, const Scalar& borderValue )
{
    //设置标志为MORPH_DILATE
    morphOp( MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}

这是只是设置好标志后调用高层函数来实现功能。

五、试用

void usage_dilate()
{
    Mat  image = imread("./smimage/1.jpg");
    //show the src image
    imshow("SRC", image);
    //get the kernel 
    Mat ele = getStructuringElement(MORPH_RECT, Size(3,3));
    Mat res;
    dilate(image, res, ele);
    //show the res image
    imshow("RES", res);
    waitKey(0);
}
void usage_erode()
{
    Mat src = imread("./smimage/1.jpg");
    //get the kernel
    Mat ele = getStructuringElement(MORPH_RECT, Size(5, 5));
    Mat res;
    erode(src, res, ele);
    //show the image
    imshow("SRC", src);
    imshow("RES", res);
    waitKey(0);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章