类别 | 选用情况 |
---|---|
Visual Studio版本 | Visual Studio 2019 |
编码语言 | C# |
EmguCV版本 | libemgucv-windesktop-4.1.0.3420 |
建议使用EmguCV版本所支持的Visual Studio版本,本代码适用于Visual Studio 2019版可直接使用,低版本如Visual Studio 2008经测试需要对代码较多修正可成功运行。
选择Windows窗体应用(.Net Framework)C#,
也可以通过选择条件“语言为C#、平台为Windows、项目类型为桌面”来缩小选择的范围。
在解决方案资源管理器中右键选择添加引用,然后浏览项目下找到你所安装的EmguCV的bin文件夹,比如D盘时路径可为D:\EmguCV\libemgucv-windesktop-4.1.0.3420\bin,可根据你的实际情况调整,选择文件下的Emgu.CV.UI.dll与Emgu.CV.World.dll添加,再勾选确认即可添加插件引用
创建好项目后双击如下图的项目窗口Form1进入Form1.cs代码编辑界面。
复制粘贴入下边提供的修正后的代码到Form1.cs中
整合所有的代码到一起并加以修正使其可运行成功。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Emgu.CV.Cuda;
using System.Diagnostics;
namespace FaceDetection
{
public static class DetectFace
{
public static void Detect(
IInputArray image, String faceFileName, String eyeFileName,
List<Rectangle> faces, List<Rectangle> eyes,
out long detectionTime)
{
Stopwatch watch;
using (InputArray iaImage = image.GetInputArray())
{
#if !(__IOS__ || NETFX_CORE)
if (iaImage.Kind == InputArray.Type.CudaGpuMat && CudaInvoke.HasCuda)
{
using (CudaCascadeClassifier face = new CudaCascadeClassifier(faceFileName))
using (CudaCascadeClassifier eye = new CudaCascadeClassifier(eyeFileName))
{
face.ScaleFactor = 1.1;
face.MinNeighbors = 10;
face.MinObjectSize = Size.Empty;
eye.ScaleFactor = 1.1;
eye.MinNeighbors = 10;
eye.MinObjectSize = Size.Empty;
watch = Stopwatch.StartNew();
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.DetectMultiScale(gpuGray, region);
Rectangle[] faceRegion = face.Convert(region);
faces.AddRange(faceRegion);
foreach (Rectangle f in faceRegion)
{
using (CudaImage<Gray, Byte> faceImg = gpuGray.GetSubRect(f))
{
//For some reason a clone is required.
//Might be a bug of CudaCascadeClassifier in opencv
using (CudaImage<Gray, Byte> clone = faceImg.Clone(null))
using (GpuMat eyeRegionMat = new GpuMat())
{
eye.DetectMultiScale(clone, eyeRegionMat);
Rectangle[] eyeRegion = eye.Convert(eyeRegionMat);
foreach (Rectangle e in eyeRegion)
{
Rectangle eyeRect = e;
eyeRect.Offset(f.X, f.Y);
eyes.Add(eyeRect);
}
}
}
}
}
watch.Stop();
}
}
else
#endif
{
//Read the HaarCascade objects
using (CascadeClassifier face = new CascadeClassifier(faceFileName))
using (CascadeClassifier eye = new CascadeClassifier(eyeFileName))
{
watch = Stopwatch.StartNew();
using (UMat ugray = new UMat())
{
CvInvoke.CvtColor(image, ugray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
//normalizes brightness and increases contrast of the image
CvInvoke.EqualizeHist(ugray, ugray);
//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(
ugray,
1.1,
10,
new Size(20, 20));
faces.AddRange(facesDetected);
foreach (Rectangle f in facesDetected)
{
//Get the region of interest on the faces
using (UMat faceRegion = new UMat(ugray, f))
{
Rectangle[] eyesDetected = eye.DetectMultiScale(
faceRegion,
1.1,
10,
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 Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Run();
}
static void Run()
{
IImage image;
//Read the files as an 8-bit Bgr image
image = new UMat("lena.jpg", ImreadModes.Color); //UMat version
//image = new Mat("lena.jpg", ImreadModes.Color); //CPU version
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)
CvInvoke.Rectangle(image, face, new Bgr(Color.Red).MCvScalar, 2);
foreach (Rectangle eye in eyes)
CvInvoke.Rectangle(image, eye, new Bgr(Color.Blue).MCvScalar, 2);
CvInvoke.Imshow("", image);//下边的屏蔽替换为本行代码
//display the image
//using (InputArray iaImage = image.GetInputArray())
// ImageViewer.Show(image, String.Format(
// "Completed face and eye detection using {0} in {1} milliseconds",
// (iaImage.Kind == InputArray.Type.CudaGpuMat && CudaInvoke.HasCuda) ? "CUDA" :
// (iaImage.IsUMat && CvInvoke.UseOpenCL) ? "OpenCL"
// : "CPU",
// detectionTime));
}
}
}
代码编辑完成后,需要在项目下 \bin\Debug 文件夹下放入一张名为lena.jpg的人脸照片,
可以自选照片重命名为lena.jpg。
将haarcascade_eye.xml与haarcascade_frontalface_default.xml文件也复制到项目下\bin\Debug文件夹下。
也可参照流程自行编辑体验其中的乐趣,也可下载参考案例直接运行修改。
VS2019项目文件链接如下:
EmguCV人脸识别的案例项目代码(C#版本的OpenCV)FaceDetection.rar