本文基于C#及dlib及emgu结合使用实现摄像头人脸定位及眼部定位,读者可以根据dlib来实现其他人脸识别的功能。
首先我先收集了实现dlib及emgu的基本功能的第三方库,其中包括一下库:
首先建立一个基于winform的窗体设计,然后引入关键库,如图:
从控件库中拖出即可,主要是实现显示图像用的
注意这里包含了CPU和GPU,本人使用的是CPU,包含人脸识别、眼部识别(其他功能可根据dlib库进行修改即可使用)
public class FaceDetecter
{
private bool USECUDA = false;
CudaCascadeClassifier face_cuda = null;
CudaCascadeClassifier eye_cuda = null;
CascadeClassifier face_cpu = null;
CascadeClassifier eye_cpu = null;
double scaleFactor = 1.1;
int MinNeighbors = 10;
public FaceDetecter(String faceFileName, String eyeFileName, bool tryUseCuda)
{
USECUDA = (tryUseCuda && CudaInvoke.HasCuda)?true:false;
if (USECUDA)
{
face_cuda = new CudaCascadeClassifier(faceFileName);
eye_cuda = new CudaCascadeClassifier(eyeFileName);
face_cuda.ScaleFactor = scaleFactor;
face_cuda.MinNeighbors = MinNeighbors;
face_cuda.MinObjectSize = Size.Empty;
eye_cuda.ScaleFactor = scaleFactor;
eye_cuda.MinNeighbors = MinNeighbors;
eye_cuda.MinObjectSize = Size.Empty;
}
else
{
face_cpu = new CascadeClassifier(faceFileName);
eye_cpu = new CascadeClassifier(eyeFileName);
;
}
}
public void predict(Mat image,List<Rectangle> faces, List<Rectangle> eyes,out long detectionTime)
{
Stopwatch watch;
watch = Stopwatch.StartNew();
if(USECUDA)
{
using (CudaImage<Bgr, Byte> gpuImage = new CudaImage<Bgr, byte>(image))
using (CudaImage<Gray, Byte> gpuGray = gpuImage.Convert<Gray, Byte>())
using (GpuMat region = new GpuMat())
{
face_cuda.DetectMultiScale(gpuGray, region);
Rectangle[] faceRegion = face_cuda.Convert(region);
faces.AddRange(faceRegion);
foreach (Rectangle f in faceRegion)
{
using (CudaImage<Gray, Byte> faceImg = gpuGray.GetSubRect(f))
{
using (CudaImage<Gray, Byte> clone = faceImg.Clone(null))
using (GpuMat eyeRegionMat = new GpuMat())
{
eye_cuda.DetectMultiScale(clone, eyeRegionMat);
Rectangle[] eyeRegion = eye_cuda.Convert(eyeRegionMat);
foreach (Rectangle e in eyeRegion)
{
Rectangle eyeRect = e;
eyeRect.Offset(f.X, f.Y);
eyes.Add(eyeRect);
}
}
}
}
}
watch.Stop();
}
else
{
using (UMat ugray = new UMat())
{
CvInvoke.CvtColor(image, ugray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
CvInvoke.EqualizeHist(ugray, ugray);
Rectangle[] facesDetected = face_cpu.DetectMultiScale(ugray, scaleFactor, MinNeighbors, new Size(20, 20));
faces.AddRange(facesDetected);
foreach (Rectangle f in facesDetected)
{
using (UMat faceRegion = new UMat(ugray, f))
{
Rectangle[] eyesDetected = eye_cpu.DetectMultiScale(faceRegion, scaleFactor, MinNeighbors, new Size(20, 20));
foreach (Rectangle e in eyesDetected)
{
Rectangle eyeRect = e;
eyeRect.Offset(f.X, f.Y);
eyes.Add(eyeRect);
}
}
}
}
watch.Stop();
}
detectionTime = watch.ElapsedMilliseconds;
}
}
public partial class FaceCheck : Form
{
private Capture capture = null;
Mat frame = new Mat();
private FaceDetecter detector = null;
public FaceCheck()
{
detector = new FaceDetecter(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase+"haarcascade_frontalface_default.xml", System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase+"haarcascade_eye.xml", true);
CvInvoke.UseOpenCL = false;
InitializeComponent();
capture = new Capture();
capture.ImageGrabbed += Capture_ImageGrabbed;
capture.Start(); //开启摄像头
}
private void Capture_ImageGrabbed(object sender, EventArgs e)
{
capture.Retrieve(frame, 0);
long detectionTime;
List<Rectangle> faces = new List<Rectangle>();
List<Rectangle> eyes = new List<Rectangle>();
detector.predict(frame, faces, eyes, out detectionTime);
foreach (Rectangle face in faces)
CvInvoke.Rectangle(frame, face, new Bgr(Color.Red).MCvScalar, 2);
foreach (Rectangle eye in eyes)
CvInvoke.Rectangle(frame, eye, new Bgr(Color.Blue).MCvScalar, 2);
captureImageBox.Image = frame;
}
private void FaceCheck_FormClosing(object sender, FormClosingEventArgs e)
{
capture.Pause();
}
}
源码:源码地址