我尝试在我的Windows Phone应用程序中应用Erosion and Dilation算法:)。
但是很难做到:(我调查了一些例子,我发现了这个http://channel9.msdn.com/coding4fun/articles/FaceLight--Silverlight-4-Real-Time-Face-Detection
Silverlight的FaceLight。
是一个非常好的例子,有Erode和Dilate算法,但我的应用程序有一些差异,FaceLight从相机拍摄照片,我希望我的应用程序从Gallery加载一些图像并应用该算法。
我按照这个步骤操作 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;
}
结果如下:没有任何反应:(
与Dilate算法相同但结果图像是空白图像。 任何想法o建议?我需要帮助。
答案 0 :(得分:0)
我很快看了你的侵蚀方法。你为什么不写一个循环(实际上有两个循环从-2到+2)来处理你试图处理的25个案例?
答案 1 :(得分:0)
虽然Erode功能看起来应该适用于灰度,但是在调用erode之前,你是否试过将图像阈值化为二进制掩码(例如rp = p> 127?255:0)?
此处为Erode函数提供的代码也永远不会将i
从0更改为<...