02-形态学操作(针对二值图像)

针对二值图

图像f,背景(像素值0),目标前景A(255), 结构元素B(255)

1  腐蚀

作用:腐蚀是一种收缩或细化操作;

简述:在图像f中,移动结构元素B的区域集合全部属于前景A;也就是说,在图像f中的某一像素点,若该处像素值为255,以结构元素B的中心位置处对应该像素点,若结构元素B大小覆盖的邻域范围内(图像f上)存在非255的值,那么该像素点就会被腐蚀掉,即变成0;

腐蚀算法编程逻辑:

 1)首先判断该处像素是否为255,若不是255,则结束,判断下一个像素;若是255,跳转步骤2;
   2) 若是255,在判断其邻域(结构元素大小)是否全是255; 若全是255,结束,判读下一个像素;若不全是255,跳转步骤3;

   3) 若存在不是255的值,则该出像素值被腐蚀,即该处像素值改为0。

c++实现代码如下:

 1 void  corrosion_binary(Mat &src, Mat& dst, int n)
 2 {
 3     std::vector<float> winTotal;
 4     src.copyTo(dst);
 5 
 6     int windows_size = n*n;
 7     int edge = n / 2;
 8 
 9     for (int i = edge; i < src.rows - edge; i++)
10     {
11         uchar * dstptr = dst.ptr(i);
12 
13         for (int j = edge; j < src.cols - edge; j++)
14         {
15 
16             float center = src.at<uchar>(i, j);
17             if (255.0 != center)
18                 continue;
19             
20             winTotal.clear();
21             for (int x = -edge; x <= edge; x++)
22             {
23                 for (int y = -edge; y <= edge; y++)
24                 {
25                     winTotal.push_back(src.at<uchar>(i + x, j + y));
26                 }
27             }
28 
29             float sum = accumulate(winTotal.begin(), winTotal.end(),0);
30            
31             float mean = sum / winTotal.size();
32 
33             if (mean != 255.0)
34                 dstptr[j] = 0;
35         }
36     }
37 }
View Code

2 膨胀

作用:膨胀则会“增长”或“粗化”二值图像中的物体,最简应用:桥接裂缝;

简述:在图像f上,移动结构元素b,与前景A有重叠的所有区域;

膨胀算法编程逻辑:
   针对图像f上的当前像素,对应结构元素B的中心位置,若在结构元素B覆盖范围(图像f上)邻域内有非0的元素,那么该像素点就被膨胀处理,即变为255; 否则,不做任何处理,运行下一像素.
c++实现代码如下:

void expension_binary(Mat &src, Mat &dst, int n)
{
    std::vector<float> winTotal;
    src.copyTo(dst);

    int windows_size = n*n;
    int edge = n / 2;

    for (int i = edge; i < src.rows - edge; i++)
    {
        uchar * dstptr = dst.ptr(i);

        for (int j = edge; j < src.cols - edge; j++)
        {

            winTotal.clear();
            for (int x = -edge; x <= edge; x++)
            {
                for (int y = -edge; y <= edge; y++)
                {
                    winTotal.push_back(src.at<uchar>(i + x, j + y));
                }
            }

            float sum = accumulate(winTotal.begin(), winTotal.end(), 0);
            if (sum > 0)
                dstptr[j] = 255;
        }
    }
}
View Code

3 开运算

简述:先腐蚀,后膨胀;

主要作用:开操作一般会平滑物体的轮廓、断开较窄的狭颈并消除细的突出物;

c++实现代码如下:

void open_operation(Mat &src, Mat &dst, int n)
{
    Mat src_temp;
    corrosion_binary(src, src_temp, n);
    expension_binary(src_temp, dst, n);
}
View Code

4 闭运算

简述:先膨胀,后腐蚀;

主要作用:也会平滑轮廓的一部分,但与开操作相反,它通常会弥合较窄的间断和细小的沟壑,消除小的空洞,填补轮廓线中的断裂。

c++实现代码如下:

void close_operation(Mat &src, Mat &dst, int n)
{
    Mat src_temp;
    expension_binary(src, src_temp, n);
    corrosion_binary(src_temp, dst, n);
}
View Code



原文地址:https://www.cnblogs.com/zhaopengpeng/p/12925092.html