Unity使用OpencvForUnity人脸识别并截取人脸区域

我使用的是unity版本是2019.2.0f

OpenCV for Unity 2.3.3

需要自取链接:https://pan.baidu.com/s/1jTyrX69zsYQWOnJxolfI9w 
提取码:smtv 

之前的链接找不到了 下面是2.2.4版本的

链接: https://pan.baidu.com/s/1IAipTQxarDSVWJMtuwfs5A

提取码: 9wvk 

using UnityEngine;
using UnityEngine.SceneManagement;
using System;
using System.Collections;
using System.Collections.Generic;
using OpenCVForUnity.ObjdetectModule;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;
using OpenCVForUnity.ImgcodecsModule;
using UnityEngine.UI;
using OpenCVForUnity.UnityUtils.Helper;

namespace OpenCVForUnityExample
{
    /// 
    /// Face Detection Example
    /// An example of human face detection using the CascadeClassifier class.
    /// http://docs.opencv.org/3.2.0/db/d28/tutorial_cascade_classifier.html
    /// 
    public class MyFaceDetection : MonoBehaviour
    {
        public static MyFaceDetection instance;
        CascadeClassifier cascade;
        public RawImage icon;

#if UNITY_WEBGL && !UNITY_EDITOR
        IEnumerator getFilePath_Coroutine;
#endif
        private void Awake()
        {
            if (instance == null)
            {
                instance = this;
            }
        }
        // Use this for initialization
        void Start ()
        {
#if UNITY_WEBGL && !UNITY_EDITOR
            getFilePath_Coroutine = Utils.getFilePathAsync("haarcascade_frontalface_alt.xml", 
            (result) => {
                getFilePath_Coroutine = null;

                cascade = new CascadeClassifier ();
                cascade.load(result);
                if (cascade.empty ()) {
                    Debug.LogError ("cascade file is not loaded. Please copy from “OpenCVForUnity/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
                }
           
                Run ();
            }, 
            (result, progress) => {
                Debug.Log ("getFilePathAsync() progress : " + result + " " + Mathf.CeilToInt (progress * 100) + "%");
            });
            StartCoroutine (getFilePath_Coroutine);
#else
            //cascade = new CascadeClassifier (Utils.getFilePath ("lbpcascade_frontalface.xml"));
            cascade = new CascadeClassifier ();
            cascade.load (Utils.getFilePath ("haarcascade_frontalface_alt.xml"));
            #if !UNITY_WSA_10_0
            if (cascade.empty ()) {
                Debug.LogError ("cascade file is not loaded. Please copy from “OpenCVForUnity/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
            }
            #endif
           // Run ();
            #endif
        }

        public bool Run ()
        {
            //加载图片
            Texture2D imgTexture = Resources.Load ("photo") as Texture2D;
            //转成Mat
            Mat imgMat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC4);
            Utils.texture2DToMat (imgTexture, imgMat);
            //转为灰度图像
            Mat grayMat = new Mat ();
            Imgproc.cvtColor (imgMat, grayMat, Imgproc.COLOR_RGBA2GRAY);
            Imgproc.equalizeHist (grayMat, grayMat);
            //检测图像中的所有脸
            MatOfRect faces = new MatOfRect ();
            if (cascade != null)
                cascade.detectMultiScale (grayMat, faces, 1.1, 3, 2, 
                    new Size (50, 50), new Size ());
            OpenCVForUnity.CoreModule.Rect[] rects = faces.toArray();            
            if (faces.toArray().Length == 1)
            {
                Debug.Log("识别到人脸" + faces.toArray().Length);
                //**********显示人脸区域
                for (int i = 0; i < rects.Length; i++)
                {
                    Debug.Log("detect faces " + rects[i]);

                    Imgproc.rectangle(imgMat, new Point(rects[i].x, rects[i].y), new Point(rects[i].x + rects[i].width, rects[i].y + rects[i].height), new Scalar(255, 0, 0, 255), 2);
                }
                Texture2D texture = new Texture2D(imgMat.cols(), imgMat.rows(), TextureFormat.RGBA32, false);
                Utils.matToTexture2D(imgMat, texture);
                icon.texture  = texture;
                //截取人脸部分
                InterceptImg(rects[0]);
                return true;
            }
            else
            {
                Debug.Log("未识别到人脸");
                return false;
            }      
        }

        /// 
        /// Raises the destroy event.
        /// 
        void OnDestroy ()
        {
            #if UNITY_WEBGL && !UNITY_EDITOR
            if (getFilePath_Coroutine != null) {
                StopCoroutine (getFilePath_Coroutine);
                ((IDisposable)getFilePath_Coroutine).Dispose ();
            }
            #endif
        }
        /// 
        /// 截取图片
        /// 
        /// 要截取的区域
        void InterceptImg(OpenCVForUnity.CoreModule.Rect rect)
        {
            //加载要截取的图片
            Texture2D imgTexture = Resources.Load("photo") as Texture2D;
            Mat cameraMat = new Mat(imgTexture.height, imgTexture.width, CvType.CV_8UC4);
            Utils.texture2DToMat(imgTexture, cameraMat);
            //截取需要的部分 rect为上面检测的人脸区域
            Mat croppedImage = new Mat(cameraMat, rect);
            //色彩转换 如果不加 图片颜色会不对
            Imgproc.cvtColor(croppedImage, croppedImage, Imgproc.COLOR_RGBA2BGRA);
            //这里截取到的图片为倒的 使用这个方法翻转一下
            Core.flip(croppedImage, croppedImage, 1);
            //保存到Assets目录下
            Imgcodecs.imwrite(Application.dataPath + "/cap.png", croppedImage);
        }
    }
}

以上为人脸识别+截取图片的全部代码,也加上了注释

这里要注意的方法是

cascade.detectMultiScale (grayMat, faces, 1.1, 3, 2, new Size (50, 50), new Size ());

detectMultiScale(image, objects, scaleFactor, minNeighbors, flags, minSize, maxSize)其中参数我百度翻译了一下

包含检测到对象的图像的CV_8U类型的矩阵
 矩形向量如果每个矩形包含检测到的对象,则矩形可能部分位于原始图像之外。
指定在每个图像比例上缩小图像大小的程度。
指定每个候选矩形应保留多少个邻居。minNeighbors 值越大,检测的准确度越高,不过耗时也越久.酌情调整.
与函数cvHaarDetectObjects中的旧级联具有相同含义的参数。它不用于新的级联。
最小可能的对象大小。小于该值的对象将被忽略。可以根据Screen 尺寸的一定比例来设置,别设置太小,不然会有一些错误干扰结果
最大可能的对象大小。大于该值的对象将被忽略。如果maxSize==minSize模型是按单个比例计算的。最大可检测尺寸,酌情调整.

在做这个功能的时候,我是要拍照然后识别人脸的,拍照保存的我之前有写在这里

以上,Over

你可能感兴趣的:(Unity3D合集)