Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image Erosion for face detection in C#

I'm trying to implement face detection in C#. I currently have a black + white outline of a photo with a face within it (Here). However i'm now trying to remove the noise and then dilate the image in order to improve reliability when i implement the detection.

The method I have so far is here:

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

As I understand it, in order to erode the image (and remove the noise), we need to check each pixel to see if it's surrounding pixels are black, and if so, then it is a border pixel and we need not keep it, which i believe my code does, so it is beyond me why it doesn't work.

Any help or pointers would be greatly appreciated

Thanks, Chris

like image 904
Chris Dobinson Avatar asked May 16 '10 19:05

Chris Dobinson


People also ask

How does image processing detect faces?

The OpenCV method is a common method in face detection. It firstly extracts the feature images into a large sample set by extracting the face Haar features in the image and then uses the AdaBoost algorithm as the face detector.

What are the four steps of image processing in a facial recognition system?

Face recognition is often described as a process that first involves four steps; they are: face detection, face alignment, feature extraction, and finally face recognition.

What is the best face detection method?

When it comes to a good, all-purpose face detector, I suggest using OpenCV's DNN face detector: It achieves a nice balance of speed and accuracy. As a deep learning-based detector, it's more accurate than its Haar cascade and HOG + Linear SVM counterparts. It's fast enough to run real-time on CPUs.

What is face detection?

Face detection -- also called facial detection -- is an artificial intelligence (AI) based computer technology used to find and identify human faces in digital images.


2 Answers

A couple of bugaboos that jump out. The image format is 24bpp but you are reading bytes. That could sorta work if it is a pure black+white image but the left pixel would be at x - 3. Indexing x by 3 would also be wise.

Indexing the row is wrong, you multiply by w, you should multiply by stride.

like image 179
Hans Passant Avatar answered Oct 18 '22 05:10

Hans Passant


you should take a look at the AForge.net Library ( http://code.google.com/p/aforge/ ). There are many different filters available for images. There you can also find examples how you can modify images directly

like image 24
user287107 Avatar answered Oct 18 '22 03:10

user287107