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
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 –
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 –
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 –