Randoom a Michael Friis production

Posted
22 March 2009 @ 9pm

Categories
C#, Facedetection, Interactive art

Tagged
, ,

You're reading Randoom, a Michael Friis production

Webcam face detection in C# using Emgu CV

Some time ago I wrote a post on how to do face detection in C# using OpenCV. I’ve since begun using the Emgu CV wrapper instead of opencvdotnet. Emgu CV is much better, in active development and it even runs on Mono. Two gotchas:

  1. You don’t have to install OpenCV, but instead have to copy the relevant dlls (included with the Emgu CV download) to the folder where you code executes.
  2. Open CV and X64 are not friends. If you’re running X64 Windows (and unless you are up to recompiling OpenCV) you have to make sure your app is compiled to X86, instead of the usual “Any CPU”.
  3. Remember to add PictureBox as per the original tutorial.

Here’s sample 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 nextFrame = cap.QueryFrame())
		{
			if (nextFrame != null)
			{
				// there's only one channel (greyscale), hence the zero index
				//var faces = nextFrame.DetectHaarCascade(haar)[0];
				Image grayframe = nextFrame.Convert();
				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");
        }
    }
}

21 Comments

[...] UPDATE: Recommend EmguCV for C# wrapping OpenCV, read an updated guide. [...]


Posted by
Stefan
10 May 2009 @ 6pm

Thank you for that code.

Does anyone have some experience about training the HaarClassifier to create xml files for other objects…


Posted by
Steven
13 May 2009 @ 8am

Thanks, Sir. A question I want to consult you, how to access my webcam? When I run the code “cap = new Capture(0);” with my wired camera, there is no problem. However, I don’t know how to access my webcam. (I know the address of my webcam)


Posted by
dee
26 June 2009 @ 3pm

Have you tried running emgu on a shared hosting server that has trust=Medium forced? it doesn’t seem to like it at all.


Posted by
friism
26 June 2009 @ 3pm

@dee Yeah — that would make sense since EmguCV runs on top of OpenCV which is un-managed C++ code.


Posted by
bijan
8 July 2009 @ 2pm

hello sir
very good your document
tanks


Posted by
bijan
8 July 2009 @ 2pm

i’m iranian


Posted by
Alex Park
29 July 2009 @ 11am

I used this code to get Facedetection working in C#

however I have this problem when i complie.

It says that ‘var’ could not b found

and ‘Emgu.CV.HarrCascade’ does not contain a definition for ‘rect’

and ‘face’ cannot be declared in this scope becaue it would give a different meaning to ‘face, which is already used in a ‘parent or current’.


Posted by
Lada
16 March 2010 @ 2pm

I have this problem when i complie:
using (Image nextFrame = cap.QueryFrame())

Cannot convert type ‘Emgu.CV.Image’ to ‘System.Drawing.Image’

Thanks for help. Lada


Posted by
Alex
20 April 2010 @ 8pm

Thanks for posting your code. This is really helpful. For those getting the compile error, you’ll need to specify params to the Image object to ensure that it’s using Engu.CV.Image and not System.Drawing.Image:

using (Image nextFrame = cap.QueryFrame())
and
Image grayframe = nextFrame.Convert();


Posted by
Alex
20 April 2010 @ 9pm

Ah, I see that the blog software is stripping out the greater-than and less-than so my code snippets got edited. Let me try again:

using (Image<Bgr, Byte> nextFrame = cap.QueryFrame())

and

Image<Gray, Byte> grayframe = nextFrame.Convert<Gray, Byte>();


Posted by
Komal
1 June 2010 @ 5pm

Hi. When i run this code i get an exception at the line

Image grayframe = nextFrame.Convert();

and it says that this “conversion is not supported by OpenCV”
Now can anyone tel me how to solve it?


Posted by
sonu
30 June 2010 @ 9am

hiii
sir
can u suggest me how o train the databse on your own..
bcoz for side view the results are worst..
or if u could suggest me a way to detect side face of a human in the video with arnd 80 % accuracy..


Posted by
sonu
16 July 2010 @ 3am

sonu ->> http://note.sonots.com/SciSoftware/haartraining.html#t1a1f262

Can someone tell me how to extract the face detected and then do some extra detection ? I just need to get the face’s image croped in all frames…

thanks in advance


Posted by
macias
26 September 2010 @ 7pm

Thank you very very much for this entry. It really was super fast to get all the things working. Tested with VS2010, after hooking up the events, and enabling timer — just worked. You are the man, Michael!


Posted by
Arpita Nagpal
6 October 2010 @ 1pm

I used this code to get Facedetection and is working in C#.I used the web camera for this.
but what if i want to detect faces from a vedio?
at this line “capture = new Capture(0)”,instead of(0),i gave the path of the vedio file like”capture = new Capture(“path.avi”) but still its not working.

what should i do if i want to get faces from vedio instead of camera capture.


Posted by
niko
11 October 2010 @ 10am

it’s really 100% work’s…thank’s
just enable timer and change

using (Image nextFrame = cap.QueryFrame())

and

Image grayframe = nextFrame.Convert();


Posted by
Fabio
20 October 2010 @ 3pm

Great code.
How could I compare the face detected by the webcam with somekind of image database, to identify that ME is ME ? Got it?
Thanks.


Posted by
friism
20 October 2010 @ 5pm

@Fabio that problem is called face recognition: http://www.google.com/search?q=face+recognition


Posted by
Ojulari Hakeem
31 October 2010 @ 11pm

Emgu CV is just like a bomb. It actually works. U can use this code,

Image image = new Image(“DSC02624.jpg”); //Read the files as an 8-bit Bgr image
Image gray = image.Convert(); //Convert it to Grayscale

Stopwatch watch = Stopwatch.StartNew();
//normalizes brightness and increases contrast of the image
gray._EqualizeHist();

//Read the HaarCascade objects
HaarCascade face = new HaarCascade(“haarcascade_frontalface_alt_tree.xml”);
HaarCascade eye = new HaarCascade(“haarcascade_eye.xml”);

//Detect the faces from the gray scale image and store the locations as rectangle
//The first dimensional is the channel
//The second dimension is the index of the rectangle in the specific channel
MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(
face,
1.1,
10,
Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
new Size(20, 20));

foreach (MCvAvgComp f in facesDetected[0])
{
//draw the face detected in the 0th (gray) channel with blue color
image.Draw(f.rect, new Bgr(Color.Blue), 2);

//Set the region of interest on the faces
gray.ROI = f.rect;
MCvAvgComp[][] eyesDetected = gray.DetectHaarCascade(
eye,
1.1,
10,
Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
new Size(20, 20));
gray.ROI = Rectangle.Empty;

foreach (MCvAvgComp e in eyesDetected[0])
{
Rectangle eyeRect = e.rect;
eyeRect.Offset(f.rect.X, f.rect.Y);
image.Draw(eyeRect, new Bgr(Color.Red), 2);
}
}

watch.Stop();
//display the image
ImageViewer.Show(image, String.Format(“Perform face and eye detection in {0} milliseconds”, watch.ElapsedMilliseconds));


Posted by
Chris
19 November 2010 @ 4am

I am having a problem with Capture();

I downloaded the Emgu sdk and ran (out of the box) some examples of webcam use, much like yours.. it worked fine.

I then did a rebuild all, and suddenly, I get this runtime error

The type initializer for ‘Emgu.CV.CvInvoke’ threw an exception.
“Unable to load DLL ‘cxcore210′: The specified module could not be found. (Exception from HRESULT: 0×8007007E)”}

THis happens on both VS2005 and VS2010

Any suggestions on how to fix this??


Leave a Comment