我试图在我的 Windows Phone 应用程序中应用侵蚀和膨胀算法:)。
但是很难做到:(我调查了一些例子,我发现了这个http://channel9.msdn.com/coding4fun/articles/FaceLight--Silverlight-4-Real-Time-Face-Detection
Silverlight 的 FaceLight。
是一个很好的例子,它有 Erode 和 Dilate 算法,但我的应用程序有一些差异,FaceLight 从相机拍照,我希望我的应用程序从图库中加载一些图像并应用该算法。
我按照以下步骤 1.- 从图库中加载图像。
PhotoChooserTask photo = new PhotoChooserTask();
photo.Completed += (s, ee) =>
{
BitmapImage image = new BitmapImage();
image.SetSource(ee.ChosenPhoto);
image.CreateOptions = BitmapCreateOptions.None;
this.imgoriginal.Source = image;
GrayTimer.Start();
};
photo.Show();
2.- 从原始图像中获取灰度图像。
WriteableBitmap grayimg = Operations.doGray(imgoriginal); // get the grayscale image
BitmapImage imggray = new BitmapImage();
stream = new MemoryStream(grayimg.ToByteArray()); // get the array of the image
this.Dispatcher.BeginInvoke(() =>
{
grayimg.SaveJpeg(stream, 320, 240, 0, 90); // resize and set quality
imggray.SetSource(stream);
grayImage.Source = imggray;// set the grayscale image in the control.
});
这个方法 DoGray()
public static WriteableBitmap doGray(Image image)
{
WriteableBitmap bitmap = new WriteableBitmap(image, null);
for (int y = 0; y < bitmap.PixelHeight; y++)
{
for (int x = 0; x < bitmap.PixelWidth; x++)
{
int pixelLocation = bitmap.PixelWidth * y + x;
int pixel = bitmap.Pixels[pixelLocation];
byte[] pixelbytes = BitConverter.GetBytes(pixel);
byte bwPixel = (byte)(.299 * pixelbytes[2] + .587 * pixelbytes[1] + .114 * pixelbytes[0]);
pixelbytes[0] = bwPixel;
pixelbytes[1] = bwPixel;
pixelbytes[2] = bwPixel;
bitmap.Pixels[pixelLocation] = BitConverter.ToInt32(pixelbytes, 0);
}
}
return bitmap;
}
一切正常。
现在我应用来自 FaceLight 的 Erode 算法。
WriteableBitmap g;
BitmapImage imggray = new BitmapImage();
imggray =(BitmapImage) grayImage.Source; // get the gray image from the Control.
g = new WriteableBitmap(imggray);
// i apply 3 times for try to see something :S
er = Operations.Erode(g);
for (int i = 1; i <= 2; i++)
{
Stream str = new MemoryStream(er.ToByteArray());
BitmapImage r = new BitmapImage();
WriteableBitmap n;
er.SaveJpeg(str, 320, 240,0, 100);
r.SetSource(str);
n = new WriteableBitmap(r);
er = Operations.Erode(n);
}
this.Dispatcher.BeginInvoke(() =>
{
stream = new MemoryStream(er.ToByteArray());
BitmapImage result = new BitmapImage();
er.SaveJpeg(stream, 320, 240, 0, 100);
result.SetSource(stream);
imgerode.Source = result;
});
这是 Erode 算法
// Process method of the Erode5x5Filter class
public static WriteableBitmap Erode(WriteableBitmap input)
{
var p = input.Pixels;
var w = input.PixelWidth;
var h = input.PixelHeight;
var result = new WriteableBitmap(w, h);
var rp = result.Pixels;
var empty = 0; // = 0
int c, cm;
int i = 0;
// Erode every pixel
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++, i++)
{
// Middle pixel
cm = p[y * w + x];
if (cm == empty) { continue; }
// Row 0
// Left pixel
if (x - 2 > 0 && y - 2 > 0)
{
c = p[(y - 2) * w + (x - 2)];
if (c == empty) { continue; }
}
// Middle left pixel
if (x - 1 > 0 && y - 2 > 0)
{
c = p[(y - 2) * w + (x - 1)];
if (c == empty) { continue; }
}
if (y - 2 > 0)
{
c = p[(y - 2) * w + x];
if (c == empty) { continue; }
}
if (x + 1 < w && y - 2 > 0)
{
c = p[(y - 2) * w + (x + 1)];
if (c == empty) { continue; }
}
if (x + 2 < w && y - 2 > 0)
{
c = p[(y - 2) * w + (x + 2)];
if (c == empty) { continue; }
}
// Row 1
// Left pixel
if (x - 2 > 0 && y - 1 > 0)
{
c = p[(y - 1) * w + (x - 2)];
if (c == empty) { continue; }
}
// ...
// ... Process the rest of the 24 neighboring pixels
// ...
// If all neighboring pixels are processed
// it's clear that the current pixel is not a boundary pixel.
rp[i] = cm;
}
}
return result;
}
这是结果:S什么也没发生:(
和扩张算法相同的问题,但结果图像是空白图像。任何想法或建议?我需要帮助。