1

我试图在我的 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什么也没发生:(

侵蚀图像

和扩张算法相同的问题,但结果图像是空白图像。任何想法或建议?我需要帮助。

4

2 回答 2

0

虽然 Erode 函数看起来应该在灰度上工作,但在调用 erode 之前,您是否尝试过将图像阈值化为二进制掩码(例如 rp = p > 127 ? 255 : 0)?

您在此处为 Erode 函数提供的代码也永远不会i从 0 更改...

于 2012-04-21T01:38:00.350 回答
0

我赶紧看了一下你的腐蚀方法。您为什么不编写一个循环(实际上是两个从 -2 到 +2 的 for 循环)来处理您要处理的 25 个案例?

于 2012-04-21T01:10:23.457 回答