unity+opencv实时检测人脸及眼睛区域检测

这是最近做的一个工作,由于要调用电脑摄像头实时检测人眼主要是检测闭眼睁眼
**

1.工具

**
1.1unity(作者用的是2020.3.25 大部分版本都ok
1.2opencv for unity(可从这个链接下载链接:https://pan.baidu.com/s/1Wti9m57-pe1et4U8LNgoCA 提取码:b0un
1.3haar模型
unity+opencv实时检测人脸及眼睛区域检测_第1张图片

2.实现

2.1首先新建一个项目
然后将opencv for unity导入
2.2
新建一个脚本这里命名为EyeDetect


using OpenCVForUnity;
using OpenCVForUnityExample;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EyeDetect : MonoBehaviour
{
    //WebCamTextureToMatExample webcamTexToMat = new WebCamTextureToMatExample();//获取摄像头画面的辅助类
    //PoseEstimator poseEstimator = new PoseEstimator();
    string face_Xml_path;//人脸识别训练数据文件XML的路径
    string eye_Xml_path;//人眼识别训练数据文件XML的路径
    Mat gray;//灰度图
    MatOfRect faceRect;//识别到的人脸区域

    CascadeClassifier classifier;//人脸识别分类器
    public static int EyesChecked=0;//是否检测到眼睛
    void Start()
    {
        //webcamTexToMat = transform.GetComponent();//获取Quad上挂载的WebCamTextureToMatExample脚本组件
        //poseEstimator = transform.GetComponent();
        face_Xml_path = Application.streamingAssetsPath + "/haarcascade_frontalface_alt2.xml";//获取人脸识别训练数据XML
        eye_Xml_path = Application.streamingAssetsPath + "/haarcascade_eye.xml";//获取人眼识别训练数据XML
        gray = new Mat();//初始化Mat
        faceRect = new MatOfRect();//初始化识别到的人脸区域
        classifier = new CascadeClassifier(face_Xml_path);//初始化人脸识别分类器        
    }

    public void  EyesFace()
    {
        Imgproc.cvtColor(transform.GetComponent<PoseEstimator>().rgbaMat, gray, Imgproc.COLOR_RGBA2GRAY);       //将获取到的摄像头画面转化为灰度图并赋值给gray

        classifier.detectMultiScale(gray, faceRect, 1.1d, 4, 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(transform.GetComponent<PoseEstimator>().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);//在原本的画面上框出人脸位置

            /*****************************************************************/

            Mat roi_gray_img = new Mat(gray, new OpenCVForUnity.Rect(0, 0, rects[i].x + rects[i].width, rects[i].y + rects[i].height));
            //Mat roi_img = new Mat(faceRect, new OpenCVForUnity.CoreModule.Rect(0, 0, rects[i].x + rects[i].width, rects[i].y + rects[i].height));
            MatOfRect eyes = new MatOfRect();
            CascadeClassifier eyecascade = new CascadeClassifier(eye_Xml_path);
            eyecascade.detectMultiScale(roi_gray_img, eyes, 1.3d, 8, 2, new Size(20, 20), new Size());
            //Debug.Log(eyes.elemSize());
            if (eyes.elemSize() > 0)
            {
                //  OpenCVForUnity.Rect[] eye_rects = eyes.toArray();
                // for (int t = 0; t < eye_rects.Length; t++)
                // {
                //Debug.Log("detect eyes " + rects[t]);
                // Imgproc.rectangle(roi_img, new Point(eye_rects[t].x, eye_rects[t].y), new Point(eye_rects[t].x + eye_rects[t].width, eye_rects[t].y + eye_rects[t].height), new Scalar(255, 255, 0, 255), 2); //黄
                // Point center = new Point((eye_rects[t].x + eye_rects[t].x + eye_rects[t].width) / 2, (eye_rects[t].y + eye_rects[t].y + eye_rects[t].height) / 2);
                //Imgproc.circle(poseEstimator.rgbaMat, center, eye_rects[t].width / 2, new Scalar(255, 255, 0, 255), 2);
                //}
              // Debug.Log("已检测到人眼");
                EyesChecked = 1;
            }
            else
            {
                EyesChecked = 0;
            }
            
        }
       
    }
}

在这里插入图片描述

到这个路径下打开并修改UPdateunity+opencv实时检测人脸及眼睛区域检测_第2张图片

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().DetectFace();//添加调用FaceDetect脚本中DetectFace画线函数的语句
                transform.GetComponent<EyeDetect>().EyesFace();//添加调用FaceDetect脚本中DetectFace画线函数的语句
                Utils.matToTexture2D(rgbaMat, texture, colors);
            }
        }

最后运行结果如图所示:
unity+opencv实时检测人脸及眼睛区域检测_第3张图片

你可能感兴趣的:(unity项目相关,unity,opencv,人工智能)