图像处理-二值形态学运算

数学形态学

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

数学形态学操作可以分为二值形态学和灰度形态学,灰度形态学由二值形态学扩展而来。数学形态学有2个基本的运算,即腐蚀和膨胀,而腐蚀和膨胀通过结合又形成了开运算和闭运算。 开运算就是先腐蚀再膨胀,闭运算就是先膨胀再腐蚀。本文介绍二值形态学变换。

 

二值形态学变换

二值形态学变换就是对二值图像进行数学形态学操作。常用操作有腐蚀、膨胀、开运算、闭运算等。腐蚀和膨胀是对白色部分(高亮部分)而言的,不是黑色部分。 膨胀就是图像中的高亮部分进行膨胀,“邻域扩张”,效果图拥有比原图更大的高亮区域。腐蚀就是原图中高亮部分被腐蚀,“邻域被蚕食”,效果图拥有比原图更小的高亮区域。

 

腐蚀

腐蚀操作会收缩(细化)图像中物体的轮廓,可以用来断开(分离)物体间的连接,消除离散点,代价是导致物体的面积比原来的面积要小。。

腐蚀的数学表达式为:

1.png

该式子表示用结构B腐蚀A,需要在B中定义一个参考点。B像在A上面移动(如图像卷积操作一般)。

1. 用结构元素,扫描图像的每一个像素

2. 用结构元素与其覆盖的二值图像做“与”操作

3. 如果都为1,结果图像的该像素为1。否则为0

也就是查找被处理图像中能不能找到和结构元素相同的矩阵。如果存在那么中心点所对应的点就为1,否则为0.下图为腐蚀操作的示意图:

2.png

 

代码实现:

Mat ErosionTransform(Mat &src,int kernelSize)
{
    Mat dst(src.rows, src.cols, src.type(), Scalar(0));
    Mat kernel = Mat::ones(kernelSize, kernelSize, CV_8UC1);
    if (src.channels() == 1) {
        int rowsSub = int(kernel.rows / 2);
        int colsSub = int(kernel.cols / 2);
        for (int i = rowsSub; i < src.rows-rowsSub; i++) {
            for (int j = colsSub; j < src.cols-colsSub; j++)
            {
                int flag = 0;
                for (int ki = 0; ki < kernel.rows; ki++)
                {
                    for (int kj = 0; kj < kernel.cols; kj++)
                    {
                            int i_ = i+ki - rowsSub;
                            int j_ = j+kj - colsSub;
                            if (src.at<uchar>(i_, j_) == 0 && kernel.at<uchar>(ki, kj) >0)
                                flag = 1;
                    }
                }
                if(!flag)
                    dst.at<uchar>(i, j) = 255;
                else
                    dst.at<uchar>(i, j) = 0;
            }
        }
    }
    return dst;
}

说明:

当输入的核是一个3x3的全1矩阵时,运行效果图如下:

3.png

 

膨胀

膨胀操作会扩大(粗化)图像中物体的轮廓,可以用来弥补(填充)物体间的孔洞,强化离散点,代价是导致物体的面积比原来的面积要大。

膨胀的公式如下:

4.png

膨胀是和腐蚀运算相反的操作,膨胀的步骤如下:

1. 用结构元素,扫描图像的每一个像素

2. 用结构元素与其覆盖的二值图像做“与”操作

3. 如果都为0,结果图像的该像素为0。否则为1

也就是在结构元素覆盖范围下,只要有一个像素符和结构元素像素相同,那么中心点对应点就为1,否则为0.

5.png

代码实现如下:

 

Mat DialateTransform(Mat &src, int kernelSize)
{
    Mat dst(src.rows, src.cols, src.type(), Scalar(0));
    Mat kernel = Mat::ones(kernelSize, kernelSize, CV_8UC1);
    if (src.channels() == 1) {
        int rowsSub = int(kernel.rows / 2);
        int colsSub = int(kernel.cols / 2);
        for (int i = rowsSub; i < src.rows - rowsSub; i++) {
            for (int j = colsSub; j < src.cols - colsSub; j++)
            {
                int flag = 0;
                for (int ki = 0; ki < kernel.rows; ki++)
                {
                    for (int kj = 0; kj < kernel.cols; kj++)
                    {
                        int i_ = i + ki - rowsSub;
                        int j_ = j + kj - colsSub;
                        if (src.at<uchar>(i_, j_) >0 && kernel.at<uchar>(ki, kj) >0)
                            flag = 1;
                    }
                }
                if (!flag)
                    dst.at<uchar>(i, j) =0;
                else
                    dst.at<uchar>(i, j) = 255;
            }
        }
    }
    return dst;
}

kernelSize=3时,运行效果图如下:

6.png

 



闭运算

闭运算是使用同一结构元对图像进行先膨胀后腐蚀的操作,可以用来弥合较窄的间断和细长的沟壑,消除物体间小的孔洞,填补轮廓线中的断裂。

闭运算=先进行膨胀运算,在进行腐蚀运算,其运行示意图如下,

7.png

 

代码实现:

Mat ClosingTransform(Mat &src, int kernelSize)
{
    Mat dialateImg = DialateTransform(src, kernelSize);
    return ErosionTransform(dialateImg, kernelSize);
}
当

 8.png


开运算

开运算是使用同一结构元对图像进行先腐蚀后膨胀的操作,可以用来平滑物体的轮廓,断开物体间较窄的连接,消除物体边沿尖锐的突出部分。

开运算 = 先腐蚀运算,再膨胀运算.示意图如下:

9.png

代码实现:

Mat OpeningTransform(Mat &src, int kernelSize)
{
    Mat erosionImg = ErosionTransform(src, kernelSize);
    return DialateTransform(erosionImg, kernelSize);
}

kernelSize=5

10.png



参考文献

[1] 百度百科.数学形态学.https://baike.baidu.com/item/%E6%95%B0%E5%AD%A6%E5%BD%A2%E6%80%81%E5%AD%A6/2594174.

[2]CSDN博客:chaolei_9527. 数学形态学运算——腐蚀、膨胀、开运算、闭运算.https://blog.csdn.net/chaolei3/article/details/79618602.2018-03-20

[3]CSDN博客:青雲-吾道乐途. 膨胀与腐蚀的彻底击破.https://blog.csdn.net/qq_37059483/article/details/77878829.2017-09-07

[4]CSDN博客:HanShanBuLeng. 形态学应用——图像开运算与闭运算.https://blog.csdn.net/hanshanbuleng/article/details/80657148.2018-06-11

首页 所有文章 机器人 计算机视觉 自然语言处理 机器学习 编程随笔 关于