Эрозия и расширение в Windows phone???

я пытаюсь применить алгоритмы Erosion и Dilation в своем приложении для Windows Phone :).

Но это очень сложно сделать :( я исследовал некоторые примеры и нашел это http://channel9.msdn.com/coding4fun/articles/FaceLight--Silverlight-4-Real-Time-Face-Detection

FaceLight для Silverlight.

Это очень хороший пример, в котором есть алгоритмы 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;
    }

Все работает нормально.

Исходное изображение

Изображение в оттенках серого

Теперь я применяю алгоритм Erode от FaceLight.

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 ничего не происходит :(

Изображение эрозии

такая же проблема с алгоритмом Dilate, но результирующее изображение — пустое. Любые идеи или предложения?? Мне нужна помощь, пожалуйста.


person Ricardo Pons    schedule 21.04.2012    source источник


Ответы (2)


Я быстро взглянул на ваш метод разрушения. Почему вы не написали цикл (на самом деле два цикла for от -2 до +2) для обработки 25 случаев, которые вы пытаетесь обработать?

person Mohammad Moghimi    schedule 21.04.2012
comment
Я не думаю, что это его код - он сказал, что это из библиотеки FaceLight. - person smocking; 21.04.2012
comment
У меня есть собственное решение: я использовал AForge.NET Framework через WCF, я отправляю изображения в WCF из Windows Phone, а WCF возвращает изображение результата :). - person Ricardo Pons; 04.05.2012

Хотя функция Erode выглядит так, как будто она должна работать в градациях серого, пытались ли вы установить для изображения пороговое значение бинарной маски (например, rp = p > 127 ? 255 : 0) перед вызовом erode?

Код, который у вас есть здесь для функции Erode, также никогда не меняет i с 0...

person smocking    schedule 21.04.2012