|
形态学基本思想:用一定形态的结构元素,去量度和提取图像中的对应形状,达到分析和识别的目的。
形态学有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
总结:图像的腐蚀处理方式,照我简单通俗的理解就是,提供一个模板区域,在目标图像上遍历每个像素点。得注意遍历的区间,具体的区间范围受模板区域由模板区域大小决定。以目标像素点为中心,跟模板大小一样的范围,对比一下相应的像素值是不是一样,如果一样,那么就保留该像素点,否则就将该目标像素点置为背景色,相当于删除该目标像素点。跟之前的灰度变化、分割等功能大同小异。当初对比的是灰度值,此时作比较的是一个范围,一块图像。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|