|
膨胀:对二值化物体边界点进行扩充,将与物体接触的所有背景点合并到该物体中,使边界向外部扩张。如果两个物体间隔较近,会将两物体连通在一起。对填补图像分割后物体的空洞有用。
膨胀效果图
<hr/>图像的膨胀,可分三种:水平膨胀、垂直膨胀、全方向膨胀。
水平膨胀:遍历目标图像中的目标区域,只考虑目标像素及其相邻的左右两个像素的灰度值,确认其与膨胀的结构元素是否有交点,即存在至少一处对应的灰度值相等。如果有交点,则处理该像素点。否则将该像素点删除。
水平膨胀所用的结构元素
源码如下:
void LevelInflation()
{
BYTE* Temp;
BYTE* p_data;
p_data = this->GetData();
int nWidth,nHeight;
nWidth = this->GetWidth();
nHeight = this->GetHeight();
if (m_pBitmapInfoHeader->biBitCount < 9)
{
Temp = new BYTE[nWidth*nHeight];
memset(Temp, (BYTE)255, nHeight*nWidth); // 目标图像中的当前点先赋成白色
for (int j = 0; j < nHeight; j++)
{
for (int i = 1; i < nWidth - 1; i++) // 由于使用1×3的结构元素,为防止越界,所以不处理最左边和最右边的两列像素
{
// 如果源图像中(-1,0)、(0,0)、(1,0)三个点之一有黑点,
// 则将目标图像中的(0,0)点赋成黑色
for(int m = 0; m < 3; m++)
{
if (*(p_data+j*nWidth+i-1+m) < 128)
{
*(Temp+j*nWidth+i) = 0;
break;
}
}
}
}
}
memcpy(p_data, Temp, nWidth*nHeight);
delete Temp;
}实现效果:
https://www.zhihu.com/video/1443960175544053760
垂直膨胀:遍历目标图像中的目标区域,只考虑目标像素及其相邻的上下两个像素的灰度值,确认其与膨胀的结构元素是否有交点,即存在至少一处对应的灰度值相等。如果有交点,则处理该像素点。否则将该像素点删除。
垂直膨胀所用的结构元素
代码如下:
void VerticalInflation()
{
BYTE* Temp;
BYTE* p_data;
p_data = this->GetData();
int nWidth,nHeight;
nWidth = this->GetWidth();
nHeight = this->GetHeight();
if (m_pBitmapInfoHeader->biBitCount < 9)
{
Temp = new BYTE[nWidth*nHeight];
memset(Temp, (BYTE)255, nHeight*nWidth); // 目标图像中的当前点先赋成白色
for (int j = 1; j < nHeight-1; j++) // 由于使用1×3的结构元素,为防止越界,所以不处理最上边和最下边的两列像素
{
for (int i = 0; i < nWidth; i++)
{
// 如果源图像中上中下三个点之一有黑点,
// 则将目标图像中的(0,0)点赋成黑色
for(int m = 0; m < 3; m++)
{
if (*(p_data+(j-1+m)*nWidth+i) < 128)
{
*(Temp+j*nWidth+i) = 0;
break;
}
}
}
}
}
memcpy(p_data, Temp, nWidth*nHeight);
delete Temp;
}实现效果:
https://www.zhihu.com/video/1443959858265923584
全方位膨胀:遍历目标图像中的目标区域,只考虑目标像素及其相邻的上下左右四个像素的灰度值,确认其与膨胀的结构元素是否有交点,即存在至少一处对应的灰度值相等。如果有交点,则处理该像素点。否则将该像素点删除。
全方向膨胀所有的结构元素
源码如下:
void DoubleInflation()
{
BYTE* Temp;
BYTE* p_data;
p_data = this->GetData();
int nWidth,nHeight;
nWidth = this->GetWidth();
nHeight = this->GetHeight();
if (m_pBitmapInfoHeader->biBitCount < 9)
{
Temp = new BYTE[nWidth*nHeight];
memset(Temp, (BYTE)255, nHeight*nWidth); // 目标图像中的当前点先赋成白色
for (int j = 1; j < nHeight-1; j++) // 为防止越界,所以不处理最上边,最左边,最右边和最下边的两列像素
{
for (int i = 1; i < nWidth-1; i++)
{
// 如果源图像中上,下,左,右四个点之一有黑点,
// 则将目标图像中的(0,0)点赋成黑色
//结构元素如下
// B[9]={0, 1, 0,
// 1, 0, 1,
// 0, 1, 0};
if (*(p_data+(j-1)*nWidth+i) < 128)
{
*(Temp+j*nWidth+i) = 0;
continue;
}
if (*(p_data+j*nWidth+i+1) < 128)
{
*(Temp+j*nWidth+i) = 0;
continue;
}
if (*(p_data+j*nWidth+i-1) < 128)
{
*(Temp+j*nWidth+i) = 0;
continue;
}
if (*(p_data+(j+1)*nWidth+i) < 128)
{
*(Temp+j*nWidth+i) = 0;
continue;
}
}
}
}
memcpy(p_data, Temp, nWidth*nHeight);
delete Temp;
}实现效果:
https://www.zhihu.com/video/1443960438211526656 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|