目录
介绍
背景
技术
传统的
3-D
皮肤纹理分析
EmguCV
EmguCV基础知识:我如何开始工作?
使用代码
如何训练原型?
“首先启用面部检测”警告?
如何提高辨识度?
如何提高较慢 CPU 的性能?
第一个选项
第二种选择
原型没有将陌生人显示为未知,为什么?
您需要什么来运行/使用此项目而不会出错?
兴趣点
你能用这篇文章和OpenCV做什么?
关于它的书籍
参考
下载 FaceRecPro 优化版:源代码,演示:所有二进制文件引用,算法增强 - 7.4 MB
下载源 - 153.8 KB
下载演示 - 2 MB
面部识别一直是世界各地许多人都在研究的问题。这个问题已经出现在多个领域和科学中,特别是在计算机科学中,对这项技术非常感兴趣的其他领域是:机电一体化、机器人、犯罪学等。在本文中,我使用EmguCV跨平台.NET研究这个有趣的话题包装到英特尔OpenCV图像处理库和C# .NET,这些库允许我实时捕获和处理捕获设备的图像。本文的主要目标是展示和解释使用具有特征脸的主成分分析(PCA)为多人实时实现人脸检测器和识别器的最简单方法,以便在多个领域实现它。
面部识别是一种计算机应用程序,由复杂的算法组成,使用数学和矩阵技术,这些算法以光栅模式(数字格式)获取图像,然后使用不同的方法逐个像素进行处理和比较,以获得更快、更可靠的结果。显然,由于这些算法、函数和例程所需的巨大计算能力,这些结果取决于用于处理此问题的机器,这些是用于解决这个现代问题的最流行的技术。
一些面部识别算法通过从对象面部的图像中提取地标或特征来识别面部。例如,算法可以分析眼睛、鼻子、颧骨和下巴的相对位置、大小和/或形状。然后使用这些特征来搜索具有匹配特征的其他图像。其他算法将人脸图像库归一化,然后压缩人脸数据,只保存图像中对人脸检测有用的数据。然后将探测图像与面部数据进行比较。最早成功的系统之一是基于应用于一组显著面部特征的模板匹配技术,提供一种压缩的面部表示。识别算法可以分为两种主要方法,几何,它着眼于区别特征,或光度,这是一种统计方法,将图像提取为值并将值与模板进行比较以消除差异。流行的识别算法包括带有特征脸的主成分分析、线性判别分析、弹性束图匹配fisherface、隐马尔可夫模型和神经元驱动的动态链接匹配。
取自[1]的文本
EigenFaces 的一个例子:
图片取自[4]
一个新出现的趋势是三维人脸识别,它声称可以实现前所未有的准确度。该技术使用3-D传感器来捕获有关面部形状的信息。然后,此信息用于识别面部表面的独特特征,例如眼窝、鼻子和下巴的轮廓。3-D面部识别的一个优点是它不会像其他技术那样受光照变化的影响。它还可以从一系列视角(包括剖面图)识别人脸。即使是完美的3D匹配技术也可能对表情敏感。为此,Technion的一个小组应用了度量几何工具将表达式视为等距。
图片取自[2]
另一个新兴趋势使用标准数字或扫描图像中捕获的皮肤视觉细节。这种称为皮肤纹理分析的技术将人皮肤中明显的独特线条、图案和斑点转化为数学空间测试表明,加入皮肤纹理分析后,面部识别性能可提高20%至25%。它通常用于安全系统,并且可以与其他生物识别技术(例如指纹或眼睛虹膜识别系统)进行比较。
取自[1]的文本
Emgu CV是英特尔OpenCV图像处理库的跨平台.NET包装器。允许从.NET兼容语言(如C#、VB、VC++、IronPython等)调用OpenCV函数。包装器可以在Mono中编译并在Linux/Mac OS X上运行。
取自[3]的文本
用我自己的话来说,EmguCV是一个很棒的Wrapper,它允许制作非常有趣的东西和计算机视觉任务。这个库集让我们在这个领域做无限量的精彩项目,EmguCV有很多功能可以让我们使用CPU和使用最新提到的GPU显著提高性能。
这个很棒的软件项目让工作和做:
如果您从未使用过此包装器,您想了解如何添加对项目的引用或解决问题,请查看C_Johnson的这篇好文章/教程:
另一个有趣的网络/博客是由mehwish87提供的关于emguCV、图像处理和面部识别的教程:
首先,声明所有要使用的变量和重要对象:
//Declaration of all variables, vectors and haarcascades
Image currentFrame;
Capture grabber;
HaarCascade face;
HaarCascade eye;
MCvFont font = new MCvFont(FONT.CV_FONT_HERSHEY_TRIPLEX, 0.5d, 0.5d);
Image result, TrainedFace = null;
Image gray = null;
List> trainingImages = new List>();
List labels= new List();
List NamePersons = new List();
int ContTrain, NumLabels, t;
string name, names = null;
然后加载haarcascade进行人脸检测,然后我做一些“程序”来为之前存储的每张图像加载之前训练过的人脸和标签:
//Load haarcascades for face detection
face = new HaarCascade("haarcascade_frontalface_alt_tree.xml");
eye = new HaarCascade("haarcascade_eye.xml");
try
{
//Load of previous trained faces and labels for each image
string Labelsinfo =
File.ReadAllText(Application.StartupPath + "/TrainedFaces/TrainedLabels.txt");
string[] Labels = Labelsinfo.Split('%');
NumLabels = Convert.ToInt16(Labels[0]);
ContTrain = NumLabels;
string LoadFaces;
for (int tf = 1; tf < NumLabels+1; tf++)
{
LoadFaces = "face" + tf + ".bmp";
trainingImages.Add(new Image
(Application.StartupPath + "/TrainedFaces/" + LoadFaces));
labels.Add(Labels[tf]);
}
}
catch(Exception e)
{
//MessageBox.Show(e.ToString());
MessageBox.Show("Nothing in binary database,
please add at least a face", "Trained faces load",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
初始化捕获设备,以及FrameGrabber为捕获的每一帧执行图像检测和处理的事件:
grabber = new Capture();
grabber.QueryFrame();
//Initialize the FrameGraber event
Application.Idle += new EventHandler(FrameGrabber);
button1.Enabled = false;
传递给FrameGrabber事件(原型的主要部分),我们使用最重要的方法和对象:DetectHaarCascade和EigenObjectRecognizer并对一帧中检测到的每个人脸执行操作:
MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(
face,
1.2,
10,
Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
new Size(20, 20));
//Action for each element detected
foreach (MCvAvgComp f in facesDetected[0])
{
t = t + 1;
result = currentFrame.Copy(f.rect).Convert().
Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
//draw the face detected in the 0th (gray) channel with blue color
currentFrame.Draw(f.rect, new Bgr(Color.Red), 2);
if (trainingImages.ToArray().Length != 0)
{
//TermCriteria for face recognition with
//numbers of trained images like maxIteration
MCvTermCriteria termCrit = new MCvTermCriteria(ContTrain, 0.001);
//Eigen face recognizer
EigenObjectRecognizer recognizer = new EigenObjectRecognizer(
trainingImages.ToArray(),
labels.ToArray(),
5000,
ref termCrit);
name = recognizer.Recognize(result);
//Draw the label for each face detected and recognized
currentFrame.Draw(name, ref font,
new Point(f.rect.X - 2, f.rect.Y - 2), new Bgr(Color.LightGreen));
}
}
参数
我以最简单的方式完成这部分,原型不断检测人脸(每一帧),您可以将检测到的人脸分别添加到图像数据库中,并带有一个标签,人脸训练后的图像将显示在imageBoxFrameGrabber中并且这个过程就完成了! !
请记住:基于PCA(主成分分析)的人脸识别算法会在检测到的人脸与存储在二进制数据库中的训练图像之间进行多次比较和匹配,因此为了提高识别的准确性,您应该添加几张图像同一个人在不同的角度、位置和亮度条件下,这种训练使这个原型变得扎实且非常准确。
例子:
训练按钮代码(这会为每个人添加训练人脸和标签):
try
{
//Trained face counter
ContTrain = ContTrain + 1;
//Get a gray frame from capture device
gray = grabber.QueryGrayFrame().Resize
(320, 240, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
//Face Detector
MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(
face,
1.2,
10,
Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
new Size(20, 20));
//Action for each element detected
foreach (MCvAvgComp f in facesDetected[0])
{
TrainedFace = currentFrame.Copy(f.rect).Convert();
break;
}
//resize face detected image for force to compare the same size with the
//test image with cubic interpolation type method
TrainedFace = result.Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
trainingImages.Add(TrainedFace);
labels.Add(textBox1.Text);
//Show face added in gray scale
imageBox1.Image = TrainedFace;
//Write the number of trained faces in a file text for further load
File.WriteAllText(Application.StartupPath +
"/TrainedFaces/TrainedLabels.txt",
trainingImages.ToArray().Length.ToString() + "%");
//Write the labels of trained faces in a file text for further load
for (int i = 1; i < trainingImages.ToArray().Length + 1; i++)
{
trainingImages.ToArray()[i - 1].Save
(Application.StartupPath + "/TrainedFaces/face" + i + ".bmp");
File.AppendAllText(Application.StartupPath +
"/TrainedFaces/TrainedLabels.txt", labels.ToArray()[i - 1] + "%");
}
MessageBox.Show(textBox1.Text + "´s face detected and added :)",
"Training OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch
{
MessageBox.Show("Enable the face detection first",
"Training Fail", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
要为模型添加人脸,您需要先启动相机和人脸识别引擎,您只需按下“检测并识别”按钮即可。
当相机在实时图像上显示您的脸时,您可以添加和训练模型。
默认参数(scale_factor=1.1, min_neighbors=3, flags=0)已针对准确而缓慢的对象检测进行了调整。
此外,您可以修改大值的大小,在代码中修改:
MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(
face,
1.1,
3,
0,
new Size(20, 20));
此外,将第三个参数修改为2500或3000而不是5000,此修改使EigenObjectRecognizer更严格/准确。
//Eigen face recognizer
EigenObjectRecognizer recognizer = new EigenObjectRecognizer(
trainingImages.ToArray(),
labels.ToArray(),
5000,
ref termCrit);
所有的图像处理算法都需要大量的计算能力,在这种情况下,用这个sw原型为CPU进行的内部处理对于速度较慢或单核CPU来说非常困难,提高这个演示性能的简单方法是使用DetectHaarCascade方法修改的参数,该方法允许减少为网络摄像头捕获的实时图像的迭代次数、批评部分和比较的数量,从而提高了应用程序的性能。
请记住:减小这些参数的值会影响识别算法的效率。
为了更快地对真实视频图像进行操作,设置为: scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING, min_size=
此外,您可以将Minsize参数修改为较大的值。
// DetectHaarCascade Config for optimal performance
MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(
face,
1.2,
2,
Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
new Size(20, 20));
获取“缩略图”或调整原始图像捕获的大小以减少该FrameGrabber方法中的处理时间修改较小尺寸的尺寸值(最初为320x240)。
例子:
//Get the current frame form capture device
currentFrame = grabber.QueryFrame().Resize
(260, 200, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
请记住在“训练”按钮中执行相同操作:
gray = grabber.QueryGrayFrame().Resize(260, 200, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
是Eigenface方法的一个限制,不是错误,而是使用EmguCV 2.4.2及更高版本上可用的LBPH算法(有优点和缺点)。
为了避免这样的错误:
请记住,这些DLL是OpenCV库,是运行任何使用EgmuCV的项目所必需的。
这是运行演示或项目的最简单方法,找到这些文件并将其复制到文件夹demo或bin文件夹(如果你想“运行”源代码)
opencv_calib3d220.dll,opencv_contrib220.dll,opencv_core220.dll,opencv_features2d220.dll,opencv_ffmpeg220.dll,opencv_flann220.dll,opencv_gpu220.dll,opencv_highgui220.dll,opencv_imgproc220.dll,opencv_legacy220.dll,opencv_ml220.dll,opencv_objdetect220.dll和opencv_video220.dll(在EmguCV中从OpenCV内容下载DLL)和Emgu.CV.dll Emgu.CV.UI.dll Emgu.Util.dll cv110.dll cvaux110.dll cvextern.dll cxcore110.dll highgui110.dll(演示下载zip中的内容)。
请记住:您可以将这些文件复制到Windows/System32/文件夹中,而忘记此项目和其他使用Emgu或openCV(Emgu.CV.dll、Emgu.CV.UI.dll、Emgu.Util)的项目的依赖问题。 dll应始终放在bin或.exe文件夹中)或在此处下载所有准备好的项目(优化版本)和文件:
我在EmguCV中使用向量时遇到了很多问题,因此,我了解了如何使用向量等组件列表,它确实适用于我的项目。
由于部分人工视觉算法对资源的巨大需求,我学习了许多图像处理、PCA和EigenFaces并优化代码。
这个项目的想法是在看到钢铁侠场景后出现的……XD
像这样的东西......
http://youtu.be/T4z11lIKnDU
OpenCV的官方参考书是:“Learning OpenCV: Computer Vision with the OpenCV Library”,来自O'Reilly (2008)。
还有数百本不特定于OpenCV的计算机视觉好书:
https://www.codeproject.com/Articles/239849/Multiple-Face-Detection-and-Recognition-in-Real-2