最近闲来无事,看了看OPENCV,有C#版本,叫EMGU,尝试写了个获取摄像头视频流,动态监测人脸的小程序。
源码下载地址http://download.youkuaiyun.com/detail/q317379184/4910645
该源码需要自行配置EMGU环境
源码如下:
//----------------------------------------------------------------------------
// Copyright (C) 2004-2012 by EMGU. All rights reserved.
//----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.GPU;
namespace CameraCapture
{
public static class DetectFace
{
public static void Detect(Image<Bgr, Byte> image, String faceFileName, String eyeFileName, List<Rectangle> faces, List<Rectangle> eyes, out long detectionTime)
{
Stopwatch watch;
if (GpuInvoke.HasCuda)
{
using (GpuCascadeClassifier face = new GpuCascadeClassifier(faceFileName))
using (GpuCascadeClassifier eye = new GpuCascadeClassifier(eyeFileName))
{
watch = Stopwatch.StartNew();
using (GpuImage<Bgr, Byte> gpuImage = new GpuImage<Bgr, byte>(image))
using (GpuImage<Gray, Byte> gpuGray = gpuImage.Convert<Gray, Byte>())
{
Rectangle[] faceRegion = face.DetectMultiScale(gpuGray, 1.1, 10, Size.Empty);
faces.AddRange(faceRegion);
foreach (Rectangle f in faceRegion)
{
using (GpuImage<Gray, Byte> faceImg = gpuGray.GetSubRect(f))
{
//For some reason a clone is required.
//Might be a bug of GpuCascadeClassifier in opencv
using (GpuImage<Gray, Byte> clone = faceImg.Clone())
{
Rectangle[] eyeRegion = eye.DetectMultiScale(clone, 1.1, 10, Size.Empty);
foreach (Rectangle e in eyeRegion)
{
Rectangle eyeRect = e;
eyeRect.Offset(f.X, f.Y);
eyes.Add(eyeRect);
}
}
}
}
}
watch.Stop();
}
}
else
{
//Read the HaarCascade objects
using (CascadeClassifier face = new CascadeClassifier(faceFileName))
using (CascadeClassifier eye = new CascadeClassifier(eyeFileName))
{
watch = Stopwatch.StartNew();
using (Image<Gray, Byte> gray = image.Convert<Gray, Byte>()) //Convert it to Grayscale
{
//normalizes brightness and increases contrast of the image
gray._EqualizeHist();
//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
Rectangle[] facesDetected = face.DetectMultiScale(
gray,
1.1,
10,
new Size(20, 20),
Size.Empty);
faces.AddRange(facesDetected);
foreach (Rectangle f in facesDetected)
{
//Set the region of interest on the faces
gray.ROI = f;
Rectangle[] eyesDetected = eye.DetectMultiScale(
gray,
1.1,
10,
new Size(20, 20),
Size.Empty);
gray.ROI = Rectangle.Empty;
foreach (Rectangle e in eyesDetected)
{
Rectangle eyeRect = e;
eyeRect.Offset(f.X, f.Y);
eyes.Add(eyeRect);
}
}
}
watch.Stop();
}
}
detectionTime = watch.ElapsedMilliseconds;
}
}
}
//----------------------------------------------------------------------------
// Copyright (C) 2004-2012 by EMGU. All rights reserved.
//----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.Util;
using Emgu.CV.UI;
using Emgu.CV.GPU;
using System.Threading;
namespace CameraCapture
{
public partial class CameraCapture : Form
{
private Capture _capture = null;
private bool _captureInProgress;
public CameraCapture()
{
InitializeComponent();
try
{
_capture = new Capture();
_capture.ImageGrabbed += ProcessFrame;
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
private void ProcessFrame(object sender, EventArgs arg)
{
Image<Bgr, Byte> frame = _capture.RetrieveBgrFrame();
//captureImageBox.Image = frame;
Image<Bgr, Byte> image = _capture.RetrieveBgrFrame();
long detectionTime;
List<Rectangle> faces = new List<Rectangle>();
List<Rectangle> eyes = new List<Rectangle>();
DetectFace.Detect(image, "haarcascade_frontalface_default.xml", "haarcascade_eye.xml", faces, eyes, out detectionTime);
foreach (Rectangle face in faces)
image.Draw(face, new Bgr(Color.Red), 2);
foreach (Rectangle eye in eyes)
image.Draw(eye, new Bgr(Color.Blue), 2);
imageBox1.Image = image;
Thread.Sleep(10);
}
private void captureButtonClick(object sender, EventArgs e)
{
if (_capture != null)
{
if (_captureInProgress)
{ //stop the capture
captureButton.Text = "Start Capture";
_capture.Pause();
}
else
{
//start the capture
captureButton.Text = "Stop";
_capture.Start();
}
_captureInProgress = !_captureInProgress;
}
}
private void ReleaseData()
{
if (_capture != null)
_capture.Dispose();
}
}
}