using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // using OpenCVSharp; using OpenCVForUnity; using OpenCVForUnity.CoreModule; using OpenCVForUnity.ImgprocModule; using OpenCVForUnity.UnityUtils; using OpenCVForUnity.ObjdetectModule; namespace DiageoWhiskyBlending { public class FaceDetecter : MonoBehaviour { private Mat gray; // 灰度图,方便识别 private Mat rotatedNewMat; private MatOfRect faceRect; // 识别到的人脸的区域 private CascadeClassifier classifier; // 人脸识别分类器 private string cascadePath; public float index = 0; // ================================================== private void Start() { // LogAllWebCam(); Init(); } private void OnDestroy() { Dispose(); } private void OnApplicationQuit() { Dispose(); } // ================================================== private void Init() { cascadePath = Application.streamingAssetsPath + "/haarcascade_frontalface_alt2.xml"; gray = new Mat(); // 初始化Mat faceRect = new MatOfRect(); // 初始化识别到的人脸的区域 classifier = new CascadeClassifier(cascadePath); // 初始化人脸识别分类器 previewMat = new Mat(); previewTexture2D = new Texture2D(440, 440, TextureFormat.RGBA32, false); return; } private void Dispose() { if (rotatedNewMat != null) { rotatedNewMat.Dispose(); rotatedNewMat = null; } if (previewMat != null) { previewMat.Dispose(); previewMat = null; } if (previewTexture2D != null) { Destroy(previewTexture2D); previewTexture2D = null; } return; } public void DetectFace(Mat rgbaMat) { rotatedNewMat = MatRotate(rgbaMat.clone()); // 旋转原数据 Imgproc.cvtColor(rotatedNewMat, gray, Imgproc.COLOR_RGBA2GRAY); // 将获取到的摄像头画面转化为灰度图并赋值给gray // mat/面部矩形向量组/识别精度越高越快越不准/面部识别次数2次以上算识别/?性能优化/最小检测尺寸/最大检测尺寸 classifier.detectMultiScale(gray, faceRect, 1.1d, 2, 2, new Size(20, 20), new Size()); // 检测gray中的人脸 OpenCVForUnity.CoreModule.Rect[] rects = faceRect.toArray(); if (rects.Length > 0) { for (int i = 0; i < rects.Length; i++) { Imgproc.rectangle(rotatedNewMat, 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即为框的宽和高 } index += Time.deltaTime; if (index > .3f) { Debug.Log("连续监测超过1s...[OK]"); GameManager.Instance.EnterLogicScene00(); } } else { // if (index > 0) // { // index -= Time.deltaTime / 2; // if (index < 0) // { index = 0; // } // } } // 深复制识别、画框数据并显示 UpdatePreview(rotatedNewMat); return; } // ================================================== // 预览画面 public Image ImagePreviewImage; private Mat previewMat; private Texture2D previewTexture2D; private void UpdatePreview(Mat value) { if (!ImagePreviewImage) { return; } previewMat = value.clone(); Utils.matToTexture2D(previewMat, previewTexture2D); ImagePreviewImage.sprite = Sprite.Create(previewTexture2D, new UnityEngine.Rect(0, 0, 440, 440), Vector2.zero); return; } // ================================================== /// /// Mat旋转方法 /// /// /// private Mat MatRotate(Mat orginalMat) { Mat rotatedMat = new Mat(orginalMat.height(), orginalMat.width(), CvType.CV_8UC4, new Scalar(0, 0, 0, 255)); // DEBUG:宽高可能相反 // mat旋转 Point center = new Point(orginalMat.cols() / 2f, orginalMat.rows() / 2f); Mat mat = Imgproc.getRotationMatrix2D(center, 90, 1); Imgproc.warpAffine(orginalMat, rotatedMat, mat, orginalMat.size()); return rotatedMat; } /// /// 预览有多少相机 /// private void LogAllWebCam() { Debug.Log($"Found {WebCamTexture.devices.Length} device...[OK]"); foreach (WebCamDevice webcamDevice in WebCamTexture.devices) { Debug.Log($"{webcamDevice.name}...[OK]"); } return; } } }