Unity人脸检测,离线通用人脸检测,基于OpenCvForUnity插件,实现摄像头画面通用人脸检测功能,适合小白入门(一)

    xiaoxiao2022-07-03  255

    本文参考博客   https://www.jianshu.com/p/7938864e9875

     

    Unity离线摄像头画面通用人脸检测,摆脱了BaiduAI的次数限制,也不需要联网

    此工程只能识别摄像头画面中脸的位置和数量,不能识别人脸的ID,即不能区分出当前识别到的人脸是谁

     

    想要实现识别对应人脸的ID,即分得清张三和李四,王二麻子也可以,实现真正的人脸识别功能,请查看本人其他博客,具体哪篇,我也不记得了,滑稽

     

    文末附此次工程文件链接

     

    效果:

     

     

     

    首先需要导入插件 OpenCV for Unity 2.2.6.unitypackage,本人用的2.2.6版本,

    插件链接:https://pan.baidu.com/s/1AocvVjlGqnLeD9ezk8idBw  提取码:9dfy 

    本插件仅供学习交流使用,禁止商用

     

    我们新建一个场景,取名FaceDetect,将窗口大小设为640x480(窗口大小根据需求自定义)

    将Main Camera的Projection设为Orthographic

    新建一个Canvas,将Canvas的Render Mode 设为 Screen Space - Camera

    新建一个Quad          操作:  在  Hierarchy面板 空白处右键--> 3D Object--> Quad

    将Quad设为Canvas 的子物体,并将Quad的Scale设为640,480,1

    如下图所示

     

     

     

     

    此时为Quad添加WebcamTextureToMacExample脚本,操作:选中Quad--> Add Component--> WebcamTextureToMacExample

    '

     

    其中Requested Device Name为摄像机名,不需要填写

    Requested Width和Requested  Height为获取画面的宽和高,默认即可

     

    此时我们启动程序,已经可以获取到摄像头画面了

     

    接下来是实现人脸识别:

     

    此时我们新建一个C#脚本 取名:FaceDetect

    将FaceDetect.cs同样添加到Quad物体上

    打开FaceDetect.cs 添加引用:

    using OpenCVForUnity; using OpenCVForUnityExample;

     

    上文添加的WebcamTextureToMacExample脚本就是OpenCvForUnity插件自带的获取摄像头画面的辅助类

    既然是识别摄像头画面,首先我们需要获取到摄像头的画面,

    打开WebcamTextureToMacExample.cs

    将51行的rgbaMat变量改为公有变量,即添加Public修饰

     

     

    既然需要识别人脸,我们需要人脸识别训练数据

    通用人脸识别数据可从GitHub上下载,

    链接:https://github.com/opencv/opencv

    本文也提供了网盘链接:

    链接:https://pan.baidu.com/s/1XiR811tPhPwBfSoS-ynw2w  提取码:wqaf 

     

    下载完后在路径data\haarcascades\下找到haarcascade_frontalface_alt2.xml文件

    此包内有很多其他的训练数据,可根据自身需求尝试一下其他的文件

    本工程已经导入了几个相关的训练数据可供使用

    新建一个StreamingAssets文件夹

    将haarcascade_frontalface_alt2.xml文件复制到该文件夹下

    haarcascade_frontalface_alt2.xml即为通用的人脸识别训练数据文件

     

     

     

    回到FaceDetect.cs脚本

     

    using System.Collections; using System.Collections.Generic; using UnityEngine; using OpenCVForUnity; using OpenCVForUnityExample; public class FaceDetect : MonoBehaviour { WebCamTextureToMatExample webcamTexToMat = new WebCamTextureToMatExample(); //获取摄像头画面的辅助类 string faceXml_path; //人脸识别训练数据文件xml的路径 Mat gray; //灰度图,方便识别 MatOfRect faceRect; //识别到的人脸的区域 CascadeClassifier classifier; //人脸识别分类器 // Start is called before the first frame update void Start() { webcamTexToMat = transform.GetComponent<WebCamTextureToMatExample>(); //获取WebCamTextureToMatExample faceXml_path = Application.streamingAssetsPath + "/haarcascade_frontalface_alt2.xml"; //读取人脸识别训练数据xml gray = new Mat(); //初始化Mat faceRect = new MatOfRect(); //初始化识别到的人脸的区域 classifier = new CascadeClassifier(faceXml_path); //初始化人脸识别分类器 } public void DetectFace() { //webcamTexToMat.rgbaMat为摄像头画面,Mat类型,Imgproc.COLOR_RGBA2GRAY为将RGBA画面转化为灰度图 Imgproc.cvtColor(webcamTexToMat.rgbaMat, gray, Imgproc.COLOR_RGBA2GRAY); //将获取到的摄像头画面转化为灰度图并赋值给gray classifier.detectMultiScale(gray, faceRect, 1.1d, 2, 2, new Size(20, 20), new Size()); //检测gray中的人脸 OpenCVForUnity.Rect[] rects = faceRect.toArray(); for (int i = 0; i < rects.Length; i++) { Imgproc.rectangle(webcamTexToMat.rgbaMat, new Point(rects[i].x, rects[i].y), new Point(rects[i].x + rects[i].width, rects[i].y + rects[i].height), new Scalar(0, 255, 0, 255), 2); //在原本的画面中画框,框出人脸额位置,其中rects[i].x和rects[i].y为框的左上角的顶点,rects[i].width、rects[i].height即为框的宽和高 } } }

    各个属性方法的作用看注释

    其中classifier.detectMultiScale(gray, faceRect, 1.1d, 2, 2, new Size(20, 20), new Size());各个参数说明:

    去官网看了一下说明,结合其他人的博客,

    gray为输入的灰度图

    faceRect为被检测到的物体的矩形向量组,保存有x,y,w,h四个参数,,比如我们检测到人脸,首先我们需要知道这个人脸的位置,其次,我们需要知道这个人脸的大小,那么(x,y)就是被检测到的人脸的左上角的坐标,而w,h分别代表宽度和高度

    scaleFactor默认为1.1,scaleFactor的值必须大于1,这个参数的作用,好像与识别速度和精度有关,相当于一个阈值,当值越大,识别速度就越快,越容易识别出对象,但精度就会下降,可能会误识别成其他的对象,当值越小,识别速度就越慢,相应的精度就会提高,不容易出现将其他物体识别成我们需要的物体,但是容易造成一个都识别不到的情况。

    第一个2为minNeighbors,看别人的博客说是指每个人脸起码被检测到两次才认为被检测到

    第二个2为flags,新版的不需要,老版好像和性能优化有关,不知道理解的对不对

    第一个new Size(20,20)为检测目标的最小尺寸minSzie,低于这个尺寸的对象不检测

    第二个new Size()为目标的最大尺寸maxSize,高于这个尺寸的对象不检测

     

    官网解释:https://docs.opencv.org/master/d1/de5/classcv_1_1CascadeClassifier.html

    此时再回到WebcamTextureToMacExample.cs

    找到228行的Update方法,将Imgproc.putText()注释掉,并添加代码

    transform.GetComponent<FaceDetect>().DetectFace();

    如下图所示:

     

    保存后

    大功告成

     

    工程文件500M,这么大,主要是OpenCvForUnity插件解压后有1个G...

    压缩后500M

    工程链接:

    链接:https://pan.baidu.com/s/1RbNq24s6oAOJOxOCP_L-lg  提取码:x43l 

     

     

     

     

    最新回复(0)