Search code examples
c#image-processingface-detection

C# - Detect face and crop image


I'm writing a HttpHandler in C# which serves resized images and blah blah blah... No troubles, we have millions of handlers to use as reference.

The problem is that I have pictures of my users taken with "traditional" sizes, as 4:3 and 16:9. But this handler will need to serve the picture in a Photo ID size (4cm by 3cm) and obviously has need of cropping around the user face. The faces positions vary a lot (aren't always at the picture center).

So, what kind of algorithm I could use to detect the face center and then crop the image around this point?


Solution

  • You can use HaarCascade class in EmguCV (DotNet port of OpenCV) http://www.emgu.com/wiki/index.php/Face_detection

    Notes in order to run this example:

    • Create a Windows Form Application
    • Add a PictureBox and a Timer (and Enable it) - Run it on a x86 system
    • Be sure you have the OpenCV relevant dlls (included with the Emgu CV download) in the folder where you code executes.
    • Adjust the path to find the Haarcascade xml (last line of the code)
    using System;
    using System.Windows.Forms;
    using System.Drawing;
    using Emgu.CV;
    using Emgu.Util;
    using Emgu.CV.Structure;
    using Emgu.CV.CvEnum;
     
    namespace opencvtut
    {
        public partial class Form1 : Form
        {
                    private Capture cap;
                    private HaarCascade haar;
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void timer1_Tick(object sender, EventArgs e)
            {
                    using (Image<Bgr, byte> nextFrame = cap.QueryFrame())
                    {
                            if (nextFrame != null)
                            {
                                    // there's only one channel (greyscale), hence the zero index
                                    //var faces = nextFrame.DetectHaarCascade(haar)[0];
                                    Image<Gray, byte> grayframe = nextFrame.Convert<Gray, byte>();
                                    var faces =
                                            grayframe.DetectHaarCascade(
                                                    haar, 1.4, 4,
                                                    HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
                                                    new Size(nextFrame.Width/8, nextFrame.Height/8)
                                                    )[0];
     
                                    foreach (var face in faces)
                                    {
                                            nextFrame.Draw(face.rect, new Bgr(0,double.MaxValue,0), 3);
                                    }
                                    pictureBox1.Image = nextFrame.ToBitmap();
                            }
                    }
            }
     
            private void Form1_Load(object sender, EventArgs e)
            {
                // passing 0 gets zeroth webcam
                            cap = new Capture(0);
                // adjust path to find your xml
                            haar = new HaarCascade(
                    "..\\..\\..\\..\\lib\\haarcascade_frontalface_alt2.xml");
            }
        }
    }