找回密码
 立即注册
查看: 221|回复: 2

图像处理 —— 腐蚀(形态学)

[复制链接]
发表于 2022-6-1 10:56 | 显示全部楼层 |阅读模式
形态学基本思想:用一定形态的结构元素,去量度和提取图像中的对应形状,达到分析和识别的目的。
形态学有4个基本算子:腐蚀、膨胀、开启、闭合。这些基本运算可以推导和组合出多种实用的算法。
腐蚀:是将图像X中每一与结构元素B全等的子集 B+X 收缩为 X。(结构必须完全相同)
腐蚀作用:消除物体的边界点,使边界向内收缩,可以把小于结构元素的物体去除。可将两个有细小连通的物体分开。该方法可以用来去除毛刺,小凸起等。如果两个物体间有细小的连通,当结构足够大时,可以将两个物体分开。









腐蚀效果图

<hr/>腐蚀方式有三种,水平腐蚀、垂直腐蚀、及全方向腐蚀。
水平腐蚀:遍历目标图像中的目标区域,只考虑目标像素及其相邻的左右两个像素的灰度值,确认其与腐蚀的结构元素是否一致,如果一致,则保留该像素点。否则将该像素点删除。
源码如下:
void LevelCorrosion()
{
        BYTE* temp;
        BYTE* p_data;

        p_data = this->GetData();
        int nHeight, nWidth;
        nHeight = this->GetHeight();
        nWidth = this->GetWidth();
        if (m_pBitmapInfoHeader->biBitCount < 9)
        {
                temp = new BYTE[nWidth*nHeight];
                memset(temp, (BYTE)255, nWidth*nHeight);
                for (int j = 0; j < nHeight; j++)
                {
                        for (int i = 1; i < nWidth-1; i++)
                        {
                                //目标图像中的当前点先赋成黑色
                                *(temp+j*nWidth+i) = 0;
                                // 如果源图像中左中右三个点之一有白点,
                                // 则将目标图像中的(0,0)点赋成白色
                                for (int m = i - 1; m < i + 2; m++)
                                {
                                        if (*(p_data+j*nWidth+m) > 128)
                                        {
                                                *(temp+j*nWidth+i) = 255;
                                        }
                                }
                        }
                }

                memcpy(p_data, temp, nWidth*nHeight);
        }

        delete temp;
}效果如下:


https://www.zhihu.com/video/1443734444532797440
垂直腐蚀:遍历目标图像中的目标区域,只考虑目标像素及其相邻的上下两个像素的灰度值,确认其与腐蚀的结构元素是否一致,如果一致,则保留该像素点。否则将该像素点删除。
源码如下:
void VerticalCorrosion()
{
        BYTE* temp;
        BYTE* p_data;

        p_data = this->GetData();
        int nHeight, nWidth;
        nHeight = this->GetHeight();
        nWidth = this->GetWidth();
        if (m_pBitmapInfoHeader->biBitCount < 9)
        {
                temp = new BYTE[nWidth*nHeight];
                memset(temp, (BYTE)255, nWidth*nHeight);
                for (int j = 1; j < nHeight -1; j++)
                {
                        for (int i = 0; i < nWidth; i++)
                        {
                                //目标图像中的当前点先赋成黑色
                                *(temp+j*nWidth+i) = 0;
                                // 如果源图像中上中下三个点之一有白点,
                                // 则将目标图像中的(0,0)点赋成白色
                                for (int m = j - 1; m < j + 2; m++)
                                {
                                        if (*(p_data+m*nWidth+i) > 128)
                                        {
                                                *(temp+j*nWidth+i) = 255;
                                        }
                                }
                        }
                }

                memcpy(p_data, temp, nWidth*nHeight);
        }

        delete temp;
}效果如下:


https://www.zhihu.com/video/1443734268363599872
全方向腐蚀:遍历目标图像中的目标区域,只考虑目标像素及其相邻的上下左右四个像素的灰度值,确认其与腐蚀的结构元素是否一致,如果一致,则保留该像素点。否则将该像素点删除。
源码如下:
void DoubleCorrosion()
{
        BYTE* temp;
        BYTE* p_data;

        p_data = this->GetData();
        int nHeight, nWidth;
        nHeight = this->GetHeight();
        nWidth = this->GetWidth();
        if (m_pBitmapInfoHeader->biBitCount < 9)
        {
                temp = new BYTE[nWidth*nHeight];
                memset(temp, (BYTE)255, nWidth*nHeight);
                for (int j = 1; j < nHeight-1; j++)
                {
                        for (int i = 1; i < nWidth-1; i++)
                        {
                                //目标图像中的当前点先赋成黑色
                                *(temp+j*nWidth+i) = 0;
                                // 如果源图像中上下左右四个点之一有白点,
                                // 则将目标图像中的(0,0)点赋成白色
                                if (*(p_data+j*nWidth+i-1) > 128)
                                {
                                        *(temp+j*nWidth+i) = 255;
                                        continue;
                                }
                                if (*(p_data+(j-1)*nWidth+i) > 128)
                                {
                                        *(temp+j*nWidth+i) = 255;
                                        continue;
                                }
                                if (*(p_data+j*nWidth+i+1) > 128)
                                {
                                        *(temp+j*nWidth+i) = 255;
                                        continue;
                                }
                                if (*(p_data+(j+1)*nWidth+i) > 128)
                                {
                                        *(temp+j*nWidth+i) = 255;
                                        continue;
                                }
                                /*if (*(p_data+j*nWidth+i) > 128)
                                {
                                        *(temp+j*nWidth+i) = 255;
                                        continue;
                                }*/
                        }
                }

                memcpy(p_data, temp, nWidth*nHeight);
        }

        delete temp;
}效果如下:


https://www.zhihu.com/video/1443881053479530497
总结:图像的腐蚀处理方式,照我简单通俗的理解就是,提供一个模板区域,在目标图像上遍历每个像素点。得注意遍历的区间,具体的区间范围受模板区域由模板区域大小决定。以目标像素点为中心,跟模板大小一样的范围,对比一下相应的像素值是不是一样,如果一样,那么就保留该像素点,否则就将该目标像素点置为背景色,相当于删除该目标像素点。跟之前的灰度变化、分割等功能大同小异。当初对比的是灰度值,此时作比较的是一个范围,一块图像。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-6-1 10:58 | 显示全部楼层
这是二值图像吗?
发表于 2022-6-1 11:02 | 显示全部楼层
灰度图
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-26 22:25 , Processed in 0.094046 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表