我使用的是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
{
/// <summary>
/// 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
/// </summary>
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;
}
}
/// <summary>
/// Raises the destroy event.
/// </summary>
void OnDestroy ()
{
#if UNITY_WEBGL && !UNITY_EDITOR
if (getFilePath_Coroutine != null) {
StopCoroutine (getFilePath_Coroutine);
((IDisposable)getFilePath_Coroutine).Dispose ();
}
#endif
}
/// <summary>
/// 截取圖檔
/// </summary>
/// <param name="rect">要截取的區域</param>
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)其中參數我百度翻譯了一下
<param name="image">包含檢測到對象的圖像的CV_8U類型的矩陣</param>
<param name="objects">矩形向量如果每個矩形包含檢測到的對象,則矩形可能部分位于原始圖像之外。</param>
<param name="scaleFactor">指定在每個圖像比例上縮小圖像大小的程度。</param>
<param name="minNeighbors">指定每個候選矩形應保留多少個鄰居。minNeighbors 值越大,檢測的準确度越高,不過耗時也越久.酌情調整.</param>
<param name="flags">與函數cvHaarDetectObjects中的舊級聯具有相同含義的參數。它不用于新的級聯。</param>
<param name="minSize">最小可能的對象大小。小于該值的對象将被忽略。可以根據Screen 尺寸的一定比例來設定,别設定太小,不然會有一些錯誤幹擾結果</param>
<param name="maxSize">最大可能的對象大小。大于該值的對象将被忽略。如果maxSize==minSize模型是按單個比例計算的。最大可檢測尺寸,酌情調整.</param>
在做這個功能的時候,我是要拍照然後識别人臉的,拍照儲存的我之前有寫在這裡
以上,Over