OpenCV C++(七)----形态学处理

在“阈值分割”中分割的结果经常包含一些干扰,有的甚至影响了目标物体的形状。数学形态学提供了一组有用的方法,能够用来调整分割区域的形状以获得比较理想的结果。常用的形态学处理方法包括: 腐蚀、膨胀、开运算、闭运算、顶帽运算、底帽运算,其中腐蚀和膨胀是最基础的方法,其他方法是两者相互组合而产生的 。

7.1、腐蚀

图像的腐蚀操作与中值平滑操作类似,它是取每一个位置的矩形邻域内值的最小值作为该位置的输出灰度值。

不同的是,这里的邻域不再单纯是矩形结构的,也可以是椭圆形结构的、十字交叉形结构的等, 它在大多数书中的定义是结构元,只是用来指明邻域结构的形状,与卷积核类似,它同样需要指定一 个锚点。

腐蚀后输出图像的总体亮度的平均值比起原图会有所降低,图像中比较亮的区域的面积会变小甚至消失,而比较暗的区域的面积会增大。

图像I与结构元S的腐蚀操作记为:

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

    Mat img = imread("Koala.jpg", IMREAD_GRAYSCALE);
    //创建矩形结构元
    Mat s = getStructuringElement(MORPH_RECT, Size(3, 3));
    //2次腐蚀操作
    Mat ErodeImg;
    erode(img, ErodeImg, s, Point(-1, -1), 2);

随着结构元尺寸的增大,灰度较暗的区域的面积也随着增大,同时灰度较亮的区域的面积就随着减小了,而且处理后的效果可以隐约看出结构元的形状,即很多重叠的矩形块,很像马赛克效果。当然,如果采用椭圆形或者十字交叉形的结构元进行腐蚀,则同样会出现类似的椭圆或者十字交叉的形状。

7.2、膨胀

膨胀是取每一个位置邻域内的最大值,膨胀后的输出图像的总体亮度的平均值比起原图会有所上升,而图像中较亮物体的尺寸会变大;相反,较暗物体的尺寸会减小,甚至消失。

图像I 和结构元S 的膨胀操作记为:

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

7.3、开运算和闭运算

7.3.1、开运算

先腐蚀后膨胀的过程称为开运算, 即

image.png

它具有消除亮度较高的细小区域、在纤细点处分离物体, 对于较大物体,可以在不明显改变其面积的情况下平滑其边界等作用。

7.3.2、闭运算

先膨胀后腐蚀, 即

image.png

它具有填充白色物体内细小黑色空洞的区域、连接临近物体、同一个结构元、多次迭代处理,也可以在不明显改变其面积的情况下平滑其边界等作用。

void 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() );

op的值如下

enum MorphTypes{
    MORPH_ERODE    = 0, //!< see #erode
    MORPH_DILATE   = 1, //!< see #dilate
    MORPH_OPEN     = 2, //!< an opening operation
                        //!< \f[\texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} ))\f]
    MORPH_CLOSE    = 3, //!< a closing operation
                        //!< \f[\texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} ))\f]
    MORPH_GRADIENT = 4, //!< a morphological gradient
                        //!< \f[\texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} )\f]
    MORPH_TOPHAT   = 5, //!< "top hat"
                        //!< \f[\texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} )\f]
    MORPH_BLACKHAT = 6, //!< "black hat"
                        //!< \f[\texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src}\f]
    MORPH_HITMISS  = 7  //!< "hit or miss"
                        //!<   .- Only supported for CV_8UC1 binary images. A tutorial can be found in the documentation
};

7.4、其他形态学处理操作

7.4.1、顶帽变换

顶帽变换的定义是图像减去开运算结果, 即

image.png

用处:

  • 可以得到原图中灰度较亮的区域, 所以又称白顶帽变换。
  • 校正不均匀光照。

7.4.2、底帽变换

底帽变换的定义是图像减去闭运算结果, 即

image.png

用处:

  • 可以得到原图中灰度较暗的区域, 所以又称黑底帽变换。

7.4.3、形态学梯度

image.png

即膨胀结果减去腐蚀结果,得到的便是图像中物体的边界。

你可能感兴趣的:(OpenCV C++(七)----形态学处理)