应用背景:在一些情况下,我们需要“增长”或者“粗化”二值图像中的物体,初等形态学运算中的膨胀操作能实现这种目的。
基本原理:在形态学中,膨胀操作是腐蚀操作的逆运算,因此可以通过对原图像的补集进行腐蚀来得到膨胀后的图像。图像A被结构元B膨胀用集合论来表示如下式:
其中,Ac为A的补集。上式表示结构元对图像A进行膨胀的结果集合是先将B相对原点旋转180度得到-B,然后使用-B对Ac进行腐蚀,最后求补集。还可用D(A,B)表示膨胀。
膨胀操作的C++实现:
void Morphology::ImgDilation(unsigned char *imgBufIn,unsigned char *imgBufOut,int imgWidth,int imgHeight,
int *TempBuf, int TempW, int TempH)
{
int lineByte=(imgWidth+3)/4*4;
int i,j,k,l;
for(i=0;i<imgHeight;i++)
{
for(j=0;j<imgWidth;j++)
{
*(imgBufIn+i*lineByte+j)=255-*(imgBufIn+i*lineByte+j);
}
}
int *tempMask=new int[TempW*TempH];
for(k=0;k<TempH;k++)
{
for(l=0;l<TempW;l++)
{
tempMask[k*TempW+l]=TempBuf[(TempH-1-k)*TempW+TempW-1-l];
}
}
int flag;
for(i=TempH/2;i<imgHeight-TempH/2;i++)
{
for(j=TempW/2;j<imgWidth-TempW/2;j++)
{
flag=1;
for(k=-TempH/2;k<=TempH/2;k++)
{
for(l=-TempW/2;l<=TempW/2;l++)
{
if(tempMask[(k+TempH/2)*TempW+l+TempW/2])
{
if(!*(imgBufIn+(i+k)*lineByte+j+l))
flag=0;
}
}
}
if(flag)
*(imgBufOut+i*lineByte+j)=255;
else
*(imgBufOut+i*lineByte+j)=0;
}
}
for(i=0;i<imgHeight;i++)
{
for(j=0;j<imgWidth;j++)
{
*(imgBufOut+i*lineByte+j)=255-*(imgBufOut+i*lineByte+j);
}
}
for(i=0;i<imgHeight;i++
{
for(j=0;j<imgWidth;j++)
{
*(imgBufIn+i*lineByte+j)=255-*(imgBufIn+i*lineByte+j);
}
}
delete []tempMask;
}
运行结果:在VS中运行MFC多文档程序,结果如下
膨胀前的lena图像
膨胀后的lena图像
从膨胀处理结果来看,图像前景区域(白色部分)增大,边界变得模糊。