本文参考整理于https://blog.csdn.net/GottaYiWanLiu/article/details/90442274
一、人脸识别
1、准备工作
下载unity:https://unity.cn/releases
下载OpenCVForUnity:https://github.com/EnoxSoftware/OpenCVForUnity/releases
下载人脸识别训练数据://download.csdn.net/download/weixin_42872122/11996839;
制作自己的训练数据,参考https://blog.csdn.net/weixin_42872122/article/details/103294393
2、操作步骤
2.1、新建unity工程,导入OpenCVForUnity资源包
2.2、设置Main Camera的投影模式为Orthographic
Perspective:透视相机,远小近大,有距离之分
Orthographic:正交相机,没有远小近大,没有距离之分
Main Camera效果如下图:
2.3、新建一个Cavas,设置其Render Mode模式为Screen Space - Camera;Render Camera上挂载Canvas,使其位于摄像机中心。
三种模式的区别,参考:https://blog.csdn.net/fdyshlk/article/details/78509909
新建一个Quad,将其设置为Canvas的子物体,调整Quad到适当位置和大小,使其能在Canvas中显示
2.4、 将导入的OpenCVForUnity中的WebCamTextureToMatExample挂载到Quad上
WebCamTextureToMatExample脚本即为OpenCVForUnity插件自带的获取摄像头画面的辅助类,即可实现调用摄像头
将 WebCamTextureToMatExample脚本第51行的代码添加Public属性
public Mat rgbaMat;//摄像头画面rgbaMat转换为公有属性,便于下一步创建的FaceDetect脚本调用
3、人脸检测
3.1、下载完的人脸识别训练数据,选用data/haarcascades/haarcascade_frontalface_alt2.xml(通用的人脸识别训练数据文件,也可以根据项目需求,选取其它功能的xml文件)
在unity下建立StreamingAssets新文件夹,将haarcascade_frontalface_alt2.xml拷贝进去
3.2、新建一个C#脚本,命名为FaceDetect,将其挂载到Quad上
编辑FaceDetect.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity;//引用OpenCVForUnity插件
using OpenCVForUnityExample;
public class FaceDetect : MonoBehaviour
{
WebCamTextureToMatExample webcamTexToMat = new WebCamTextureToMatExample();//获取摄像头画面的辅助类
string face_Xml_path;//人脸识别训练数据文件XML的路径
Mat gray;//灰度图
MatOfRect faceRect;//识别到的人脸区域
CascadeClassifier classifier;//人脸识别分类器
void Start()
{
webcamTexToMat = transform.GetComponent<WebCamTextureToMatExample>();//获取Quad上挂载的WebCamTextureToMatExample脚本组件
face_Xml_path = Application.streamingAssetsPath + "/haarcascade_frontalface_alt2.xml";//获取人脸识别训练数据XML
gray = new Mat();//初始化Mat
faceRect = new MatOfRect();//初始化识别到的人脸区域
classifier = new CascadeClassifier(face_Xml_path);//初始化人脸识别分类器
}
public void DetectFace()
{
Imgproc.cvtColor(webcamTexToMat.rgbaMat, gray, Imgproc.COLOR_RGBA2GRAY); //将获取到的摄像头画面转化为灰度图并赋值给gray
classifier.detectMultiScale(gray, faceRect, 1.1d, 2, 2, new Size(20, 20), new Size());//检测到gray灰度图中的人脸
/*1.1d为scaleFactor,必须大于1,值越大速度越快精度越低,反之值越小速度越慢精度越高
2为minNeighbors,最少检测到两次才认为是被检测到
2为flags,性能参数
new Size(20, 20)为检测目标的最小尺寸,低于这个尺寸的不检测,或者不设置阈值
new Size(100, 100)为检测目标的最大尺寸,高于这个尺寸的不检测,或者不设置阈值
*/
OpenCVForUnity.Rect[] rects = faceRect.toArray();
//faceRect为被检测到物体的矩形向量组,保存x、y、w、h四个参数,rects[i].x和rects[i].y为框左上角顶点rects[i].width和rects[i].height为框的宽和高
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);//在原本的画面上框出人脸位置
}
}
}
3.3、 再编辑WebCamTextureToMatExample脚本,将第228行update中的自带的画框代码注释掉
添加调用FaceDetect脚本中DetectFace画线函数的语句
void Update ()
{
if (hasInitDone && webCamTexture.isPlaying && webCamTexture.didUpdateThisFrame) {
Utils.webCamTextureToMat (webCamTexture, rgbaMat, colors);
//注释掉Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
transform.GetComponent<FaceDetect>().DetectFace();//添加调用FaceDetect脚本中DetectFace画线函数的语句
Utils.matToTexture2D (rgbaMat, texture, colors);
}
}
4、大功告成
Ps:蓝色笑脸是自己画的,绿色框框是真实的(狗头保命)
------------------------------------------------------------这是分割线 ------------------------------------------------------------
二、区分检测对象
1、