2010-05-16 11 views
6

Próbuję zaimplementować wykrywanie twarzy w języku C#. Obecnie mam czarno-biały kontur zdjęcia z twarzą w nim (Here). Jednak teraz próbuję usunąć szum, a następnie rozszerzyć obraz w celu zwiększenia niezawodności, gdy wdrażam wykrywanie.Erozja obrazu do wykrywania twarzy w języku C#

Metoda mam tak daleko jest tutaj:

  using System; 
using System.Collections.Generic 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Drawing.Imaging; 

namespace ImageErosion 
{ 
    public partial class Form1 : Form 
    { 
     public int CompareEmptyColor { get; set; } 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void btErodeImage_Click(object sender, EventArgs e) 
     { 
      Image inputImage = pbInputImage.Image; 

      Image result = Process(inputImage); 

      pbInputImage.Image = result; 
     } 

     unsafe public Image Process(Image input) 
     { 
      Bitmap bmp = (Bitmap)input; 
      Bitmap bmpSrc = (Bitmap)input; 

      BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), 
           ImageLockMode.ReadWrite, 
           PixelFormat.Format1bppIndexed); 

      int stride = bmData.Stride; 
      int stride2 = bmData.Stride * 2; 
      IntPtr Scan0 = bmData.Scan0; 

      byte* p = (byte*)(void*)Scan0; 

      int nOffset = stride - bmp.Width * 3; 
      int nWidth = bmp.Width - 2; 
      int nHeight = bmp.Height - 2; 

      var w = bmp.Width; 
      var h = bmp.Height; 

      var rp = p; 
      var empty = CompareEmptyColor; 
      byte c, cm; 
      int i = 0; 

      // Erode every pixel 
      for (int y = 0; y < h; y++) 
      { 
       for (int x = 0; x < w; x += 3, i++) 
       { 
        // Middle pixel 
        cm = p[y * stride + x]; 
        if (cm == empty) { continue; } 

        #region FirstRow 
        // Row 0 
        // Left pixel 
        if (x - 3 > 0 && y - 2 > 0) 
        { 
         c = p[(y - 2) * stride + (x - 3)]; 
         if (c == empty) { continue; } 
        } 
        // Middle left pixel 
        if (x - 2 > 0 && y - 2 > 0) 
        { 
         c = p[(y - 2) * stride + (x - 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 1 > 0 && y - 2 > 0) 
        { 
         c = p[(y - 2) * stride + (x - 1)]; 
         if (c == empty) { continue; } 
        } 
        if (y - 2 > 0) 
        { 
         c = p[(y - 2) * stride + x]; 
         if (c == empty) { continue; } 
        } 
        if (x + 1 < w && y - 2 > 0) 
        { 
         c = p[(y - 2) * stride + (x + 1)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 2 < w && y - 2 > 0) 
        { 
         c = p[(y - 2) * stride + (x + 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 3 < w && y - 2 > 0) 
        { 
         c = p[(y - 2) * stride + (x + 3)]; 
         if (c == empty) { continue; } 
        } 
        #endregion 

        #region SecondRow 
        // Row 1 
        // Left pixel 
        if (x - 3 > 0 && y - 1 > 0) 
        { 
         c = p[(y - 1) * stride + (x - 3)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 2 > 0 && y - 1 > 0) 
        { 
         c = p[(y - 1) * stride + (x - 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 1 > 0 && y - 1 > 0) 
        { 
         c = p[(y - 1) * stride + (x - 1)]; 
         if (c == empty) { continue; } 
        } 
        if (y - 1 > 0) 
        { 
         c = p[(y - 1) * stride + x]; 
         if (c == empty) { continue; } 
        } 
        if (x + 1 < w && y - 1 > 0) 
        { 
         c = p[(y - 1) * stride + (x + 1)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 2 < w && y - 1 > 0) 
        { 
         c = p[(y - 1) * stride + (x + 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 3 < w && y - 1 > 0) 
        { 
         c = p[(y - 1) * stride + (x + 3)]; 
         if (c == empty) { continue; } 
        } 

        #endregion 

        #region ThirdRow 
        // Row 2 
        if (x - 3 > 0) 
        { 
         c = p[y * stride + (x - 3)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 2 > 0) 
        { 
         c = p[y * stride + (x - 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 1 > 0) 
        { 
         c = p[y * stride + (x - 1)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 1 < w) 
        { 
         c = p[y * stride + (x + 1)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 2 < w) 
        { 
         c = p[y * stride + (x + 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 3 < w) 
        { 
         c = p[y * stride + (x + 3)]; 
         if (c == empty) { continue; } 
        } 
        #endregion 

        #region FourthRow 
        // Row 3 
        if (x - 3 > 0 && y + 1 < h) 
        { 
         c = p[(y + 1) * stride + (x - 3)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 2 > 0 && y + 1 < h) 
        { 
         c = p[(y + 1) * stride + (x - 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 1 > 0 && y + 1 < h) 
        { 
         c = p[(y + 1) * stride + (x - 1)]; 
         if (c == empty) { continue; } 
        } 
        if (y + 1 < h) 
        { 
         c = p[(y + 1) * stride + x]; 
         if (c == empty) { continue; } 
        } 
        if (x + 1 < w && y + 1 < h) 
        { 
         c = p[(y + 1) * stride + (x + 1)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 2 < w && y + 1 < h) 
        { 
         c = p[(y + 1) * stride + (x + 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 3 < w && y + 1 < h) 
        { 
         c = p[(y + 1) * stride + (x + 3)]; 
         if (c == empty) { continue; } 
        } 
        #endregion 

        #region FifthRow 
        // Row 4 
        if (x - 3 > 0 && y + 2 < h) 
        { 
         c = p[(y + 2) * stride + (x - 3)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 2 > 0 && y + 2 < h) 
        { 
         c = p[(y + 2) * stride + (x - 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x - 1 > 0 && y + 2 < h) 
        { 
         c = p[(y + 2) * stride + (x - 1)]; 
         if (c == empty) { continue; } 
        } 
        if (y + 2 < h) 
        { 
         c = p[(y + 2) * stride + x]; 
         if (c == empty) { continue; } 
        } 
        if (x + 1 < w && y + 2 < h) 
        { 
         c = p[(y + 2) * stride + (x + 1)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 2 < w && y + 2 < h) 
        { 
         c = p[(y + 2) * stride + (x + 2)]; 
         if (c == empty) { continue; } 
        } 
        if (x + 3 < w && y + 2 < h) 
        { 
         c = p[(y + 2) * stride + (x + 3)]; 
         if (c == empty) { continue; } 
        } 
        #endregion 

        // If all neighboring pixels are processed 
        // it's clear that the current pixel is not a boundary pixel. 
        rp[i] = cm; 
       } 
      } 

      bmpSrc.UnlockBits(bmData); 
      return bmpSrc; 
     } 
    } 
} 

Jak rozumiem, w celu zachwiania obrazu (i usunąć szumy), musimy sprawdzić każdy piksel, aby zobaczyć, czy to otaczających pikseli są czarne, a jeśli tak, to jest to piksel na granicy i nie musimy go przechowywać, co moim zdaniem robi mój kod, więc jest ponad mną, dlaczego to nie działa.

Każda pomoc lub wskazówki będą bardzo mile widziane

Dzięki, Chris

Odpowiedz

2

Kilka słabszej że wyskoczyć. Format obrazu wynosi 24bpp, ale czytasz bajty. Mogłoby to działać, gdyby był czysto czarno-białym obrazem, ale lewy piksel byłby na x - 3. Indeksowanie x 3 również byłoby rozsądne.

Indeksowanie wiersza jest nieprawidłowe, pomnożenie przez w, należy pomnożyć przez krok.

+0

Wielkie dzięki za odpowiedź Hans! Zaktualizowałem swoją metodę, aby uwzględnić sugerowane poprawki, ale bez skutku :(Po uruchomieniu metody na obrazie nie ma zmian. Czy coś przeoczyłem? Jeszcze raz dziękuję! Chris –

+0

Nie wiem. Jeśli potrzebujesz pomocy debugowanie tego, zaktualizuj kod w swoim pytaniu, opublikuj link do przykładowego obrazu i wyjaśnij, jak mierzysz sukces –

+0

Stworzyłem rozwiązanie dla tej metody i opublikowałem powyższy kod.Proszę zawiera tylko 1 formularz z obrazkiem (pbInputImage) i przycisk (btErodeImage) Ustawiłem obrazek skrzynki obrazkowej na: http://img192.imageshack.us/img192/5821/blackscale.png Wyniki, których oczekiwałbym, byłyby całkiem wiele losowych białych kropek, a niektóre z nich w większości białych, aby zmienić się na czarne, podobne do tego: http://img232.imageshack.us/img232/2917/ erosionresult.png Mam nadzieję, że tego właśnie się spodziewałeś? Wielkie dzięki jeszcze raz, Chris –

1

powinieneś rzucić okiem na bibliotekę AForge.net (http://code.google.com/p/aforge/). Dostępnych jest wiele różnych filtrów obrazów. Tam możesz również znaleźć przykłady, jak możesz modyfikować obrazy bezpośrednio

0

Dlaczego nie używasz openCV? Dilate jest tam bezpośrednią funkcją i jest generalnie bardziej optymalny dla wszystkich obrazów.

Powiązane problemy