二值图像的轮廓提取对于图像识别,图像分割有着重要意义。该算法的核心就是将图像目标的内部点消除。所谓内部点,我们要根据当前像素点的邻域来进行判断,假设邻域窗口为3*3窗口,如果当前像素P(x,y)的八个邻域像素满足如下条件,则该点即内部点:
1,P(x,y)为目标像素,假设目标像素为黑色0,背景像素为白色255,那么P(x,y)=0;
2,P(x,y)的八个邻域像素均为目标像素0;
我们把满足条件的内部点删除,换为背景点255,即可得到图像轮廓。
内部点如下图所示:
Fig.1内部点
[函数代码]
///
/// Contour Extraction process.
///
/// The source image.
///
public static WriteableBitmap ContourExtraction(WriteableBitmap src)
{
if (src != null)
{
int w = src.PixelWidth;
int h = src.PixelHeight;
WriteableBitmap srcImage = new WriteableBitmap(w, h);
byte[] temp = src.PixelBuffer.ToArray();
byte[] tempMask = (byte[])temp.Clone();
for (int j = 1; j < h-1; j++)
{
for (int i = 4; i < w*4-4; i+=4)
{
if ((tempMask[i + j * w * 4] == 0) && (tempMask[i - 4 + j * w * 4] == 0) && (tempMask[i + 4 + j * w * 4] == 0) && (tempMask[i - 4 + (j - 1) * w * 4] == 0)
&& (tempMask[i - 4 + (j + 1) * w * 4] == 0) && (tempMask[i + (j - 1) * w * 4] == 0) && (tempMask[i + (j + 1) * w * 4] == 0)
&& (tempMask[i + 4 + (j - 1) * w * 4] == 0) && (tempMask[i + 4 + (j + 1) * w * 4] == 0))
{
temp[i + j * w * 4] = (byte)255;
temp[i + 1 + j * w * 4] = (byte)255;
temp[i + 2 + j * w * 4] = (byte)255;
}
}
}
Stream sTemp = srcImage.PixelBuffer.AsStream();
sTemp.Seek(0, SeekOrigin.Begin);
sTemp.Write(temp, 0, w * 4 * h);
return srcImage;
}
else
{
return null;
}
}
[图像效果]
Fig.2二值图像 Fig.3轮廓图像