2010-05-16 3 views
6

Я пытаюсь реализовать распознавание лиц в C#. В настоящее время у меня есть черно-белый контур фотографии с лицом внутри (Here). Однако теперь я пытаюсь удалить шум, а затем расширить изображение, чтобы повысить надежность при реализации обнаружения.Изображение Эрозия для обнаружения лица в C#

Метод, который я до сих пор здесь:

  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; 
     } 
    } 
} 

Как я понимаю, для того, чтобы подорвать имидж (и удалить шум), мы должны проверить каждый пиксель, чтобы увидеть, если он окружающих пикселей являются черными, и если да, то это пограничный пиксель, и нам не нужно его хранить, и я считаю, что мой код делает, так что это вне меня, почему это не работает.

Любая помощь или указатели будут весьма благодарны

Спасибо, Крис

ответ

2

Пару жупелов, что выскакивают. Формат изображения - 24bpp, но вы читаете байты. Это может быть выполнено, если это чисто черно-белое изображение, но левый пиксель будет равен x - 3. Индексирование x на 3 также было бы разумным.

Индексирование строки неверно, вы умножаетесь на w, вы должны умножаться на шаг.

+0

Большое спасибо за ответ Ганс! Я обновил свой метод, чтобы включить предлагаемые исправления, но безрезультатно :(При запуске метода на изображении его нет. Я пропустил что-то? Еще раз спасибо! Chris –

+0

Я не знаю. отлаживая это, обновляйте код в своем вопросе, разместите ссылку на образец изображения и объясните, как вы измеряете успех. –

+0

Я создал решение для этого метода и разместил этот код выше. Решение содержит только 1 форму с изображением (pbInputImage) и кнопку (btErodeImage). Я установил изображение окна с изображениями: http://img192.imageshack.us/img192/5821/blackscale.png Результаты, которые я ожидал бы для много случайных белых точек и некоторые из них вокруг большей части белого, чтобы перейти на черный, похожий на это: http://img232.imageshack.us/img232/2917/ erosionresult.png Надеюсь, это то, чего вы ожидали? Еще раз спасибо, Chris –

1

вы должны взглянуть на библиотеку AForge.net (http://code.google.com/p/aforge/). Для изображений доступно множество различных фильтров. Там вы также можете найти примеры, как можно напрямую изменять изображения

0

Почему вы не используете openCV? Dilate является прямой функцией и, как правило, более оптимальной для всех изображений.

Смежные вопросы