腐蚀操作描述为:扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作:如果都为1,结果图像的该像素为1,否则为0。
膨胀操作描述为:扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作:如果都为0,结果图像的该像素为0,否则为1。
以上都是关于二值图像的形态学操作,对于灰度图像:
-
腐蚀操作
其中,g(x,y)为腐蚀后的灰度图像,f(x,y)为原灰度图像,B为结构元素。腐蚀运算是由结构元素确定的邻域块中选取图像值与结构元素值的差的最小值。
-
膨胀操作
其中,g(x,y)为腐蚀后的灰度图像,f(x,y)为原灰度图像,B为结构元素。 膨胀运算是由结构元素确定的邻域块中选取图像值与结构元素值的和的最大值。
在灰度图的形态学操作中,一般选择“平摊”的结构元素,即结构元素B的值为0,则上面对灰度图的形态学操作可简化如下:
void Erodible(const unsigned char * src, // [in] image data
const unsigned int nWidth, // [in] image width
const unsigned int nHeight, // [in] image height
const unsigned int nThick, // [in] erodible thickness
unsigned char * dest) // [out] erodible result
{
unsigned int i, j, i0, j0;
memset(dest, 1, nWidth*nHeight);
for (i=nThick; i<nHeight-nThick; i++)
{
for (j=nThick; j<nWidth-nThick; j++)
{
if(src[i*nWidth+j]==0)
{
dest[i*nWidth+j]=0;
continue;
}
for(i0=i-nThick;i0<=i+nThick;i0++)
{
for(j0=j-nThick;j0<=j+nThick;j0++)
{
if(src[i0*nWidth+j0]==0)
{
dest[i*nWidth+j]=0;
continue;
}
}
}
}
}
}
void Dilation(const unsigned char * src, // [in] image data
const unsigned int nWidth, // [in] image width
const unsigned int nHeight, // [in] image height
const unsigned int nThick, // [in] erodible thickness
unsigned char * dest) // [out] erodible result
{
unsigned int i, j, i0, j0;
memset(dest, 0, nHeight*nWidth);
for (i=nThick; i<nHeight-nThick; i++)
{
for (j=nThick; j<nWidth-nThick; j++)
{
if(src[i*nWidth+j]>0)
{
dest[i*nWidth+j]=1;
continue;
}
for(i0=i-nThick;i0<=i+nThick;i0++)
{
for(j0=j-nThick;j0<=j+nThick;j0++)
{
if(src[i0*nWidth+j0]>0)
{
dest[i*nWidth+j]=1;
continue;
}
}
}
}
}
}