Last active
October 21, 2018 06:58
-
-
Save toshinoritakata/9abc589e87031092c00b969c1709773f to your computer and use it in GitHub Desktop.
連載3 顔検出単体版
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System; | |
#if UNITY_5_3 || UNITY_5_3_OR_NEWER | |
using UnityEngine.SceneManagement; | |
#endif | |
using OpenCVForUnity; | |
namespace OpenCVForUnityExample | |
{ | |
/// <summary> | |
/// Face Detection WebCamTexture Example | |
/// An example of detecting human face in a image of WebCamTexture using the CascadeClassifier class. | |
/// http://docs.opencv.org/3.2.0/db/d28/tutorial_cascade_classifier.html | |
/// </summary> | |
[RequireComponent (typeof(WebCamTextureToMatHelper))] | |
public class FaceDetectionWebCamTextureExample : MonoBehaviour | |
{ | |
[SerializeField] UnityEngine.UI.Image[] _mask; // maskを配列にする | |
[SerializeField] Vector2 _offset = new Vector2(320, 240); | |
/// <summary> | |
/// The gray mat. | |
/// </summary> | |
Mat grayMat; | |
/// <summary> | |
/// The texture. | |
/// </summary> | |
Texture2D texture; | |
/// <summary> | |
/// The cascade. | |
/// </summary> | |
CascadeClassifier cascade; | |
/// <summary> | |
/// The faces. | |
/// </summary> | |
MatOfRect faces; | |
/// <summary> | |
/// The webcam texture to mat helper. | |
/// </summary> | |
WebCamTextureToMatHelper webCamTextureToMatHelper; | |
/// <summary> | |
/// The FPS monitor. | |
/// </summary> | |
FpsMonitor fpsMonitor; | |
#if UNITY_ANDROID && !UNITY_EDITOR | |
float rearCameraRequestedFPS; | |
#endif | |
#if UNITY_WEBGL && !UNITY_EDITOR | |
Stack<IEnumerator> coroutines = new Stack<IEnumerator> (); | |
#endif | |
// Use this for initialization | |
void Start () | |
{ | |
fpsMonitor = GetComponent<FpsMonitor> (); | |
webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper> (); | |
#if UNITY_WEBGL && !UNITY_EDITOR | |
var getFilePath_Coroutine = Utils.getFilePathAsync ("lbpcascade_frontalface.xml", (result) => { | |
coroutines.Clear (); | |
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. "); | |
} | |
webCamTextureToMatHelper.Initialize (); | |
}); | |
coroutines.Push (getFilePath_Coroutine); | |
StartCoroutine (getFilePath_Coroutine); | |
#else | |
cascade = new CascadeClassifier (); | |
cascade.load (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 | |
#if UNITY_ANDROID && !UNITY_EDITOR | |
// Set the requestedFPS parameter to avoid the problem of the WebCamTexture image becoming low light on some Android devices. (Pixel, pixel 2) | |
// https://forum.unity.com/threads/android-webcamtexture-in-low-light-only-some-models.520656/ | |
// https://forum.unity.com/threads/released-opencv-for-unity.277080/page-33#post-3445178 | |
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS; | |
if (webCamTextureToMatHelper.requestedIsFrontFacing) { | |
webCamTextureToMatHelper.requestedFPS = 15; | |
webCamTextureToMatHelper.Initialize (); | |
} else { | |
webCamTextureToMatHelper.Initialize (); | |
} | |
#else | |
webCamTextureToMatHelper.Initialize (); | |
#endif | |
#endif | |
} | |
/// <summary> | |
/// Raises the web cam texture to mat helper initialized event. | |
/// </summary> | |
public void OnWebCamTextureToMatHelperInitialized () | |
{ | |
Debug.Log ("OnWebCamTextureToMatHelperInitialized"); | |
Mat webCamTextureMat = webCamTextureToMatHelper.GetMat (); | |
texture = new Texture2D (webCamTextureMat.cols (), webCamTextureMat.rows (), TextureFormat.RGBA32, false); | |
gameObject.GetComponent<Renderer> ().material.mainTexture = texture; | |
gameObject.transform.localScale = new Vector3 (webCamTextureMat.cols (), webCamTextureMat.rows (), 1); | |
Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation); | |
if (fpsMonitor != null){ | |
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString()); | |
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString()); | |
fpsMonitor.Add ("orientation", Screen.orientation.ToString()); | |
} | |
float width = webCamTextureMat.width (); | |
float height = webCamTextureMat.height (); | |
float widthScale = (float)Screen.width / width; | |
float heightScale = (float)Screen.height / height; | |
if (widthScale < heightScale) { | |
Camera.main.orthographicSize = (width * (float)Screen.height / (float)Screen.width) / 2; | |
} else { | |
Camera.main.orthographicSize = height / 2; | |
} | |
grayMat = new Mat (webCamTextureMat.rows (), webCamTextureMat.cols (), CvType.CV_8UC1); | |
faces = new MatOfRect (); | |
} | |
/// <summary> | |
/// Raises the web cam texture to mat helper disposed event. | |
/// </summary> | |
public void OnWebCamTextureToMatHelperDisposed () | |
{ | |
Debug.Log ("OnWebCamTextureToMatHelperDisposed"); | |
if (grayMat != null) | |
grayMat.Dispose (); | |
if (texture != null) { | |
Texture2D.Destroy(texture); | |
texture = null; | |
} | |
if (faces != null) | |
faces.Dispose (); | |
} | |
/// <summary> | |
/// Raises the web cam texture to mat helper error occurred event. | |
/// </summary> | |
/// <param name="errorCode">Error code.</param> | |
public void OnWebCamTextureToMatHelperErrorOccurred (WebCamTextureToMatHelper.ErrorCode errorCode) | |
{ | |
Debug.Log ("OnWebCamTextureToMatHelperErrorOccurred " + errorCode); | |
} | |
// Update is called once per frame | |
void Update () | |
{ | |
if (webCamTextureToMatHelper.IsPlaying () && webCamTextureToMatHelper.DidUpdateThisFrame ()) { | |
Mat rgbaMat = webCamTextureToMatHelper.GetMat (); | |
Imgproc.cvtColor (rgbaMat, grayMat, Imgproc.COLOR_RGBA2GRAY); | |
Imgproc.equalizeHist (grayMat, grayMat); | |
if (cascade != null) | |
cascade.detectMultiScale (grayMat, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE | |
new Size (grayMat.cols () * 0.2, grayMat.rows () * 0.2), new Size ()); | |
OpenCVForUnity.Rect[] rects = faces.toArray (); | |
// お面オブジェクトすべて非表示にする | |
foreach (var item in _mask) { item.enabled = false; } | |
for (int i = 0; i < rects.Length; i++) { | |
// Debug.Log ("detect faces " + rects [i]); | |
var cx = rects[i].x + rects[i].width / 2f; | |
var cy = rects[i].y + rects[i].height / 2f; | |
if (i < _mask.Length) { | |
// お面を表示 | |
_mask[i].enabled = true; | |
_mask[i].transform.localPosition = new Vector3(cx-_offset.x, -cy+_offset.y, 0); | |
} | |
} | |
//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); | |
Utils.fastMatToTexture2D (rgbaMat, texture); | |
} | |
} | |
/// <summary> | |
/// Raises the destroy event. | |
/// </summary> | |
void OnDestroy () | |
{ | |
webCamTextureToMatHelper.Dispose (); | |
if (cascade != null) | |
cascade.Dispose (); | |
#if UNITY_WEBGL && !UNITY_EDITOR | |
foreach (var coroutine in coroutines) { | |
StopCoroutine (coroutine); | |
((IDisposable)coroutine).Dispose (); | |
} | |
#endif | |
} | |
/// <summary> | |
/// Raises the back button click event. | |
/// </summary> | |
public void OnBackButtonClick () | |
{ | |
#if UNITY_5_3 || UNITY_5_3_OR_NEWER | |
SceneManager.LoadScene ("OpenCVForUnityExample"); | |
#else | |
Application.LoadLevel ("OpenCVForUnityExample"); | |
#endif | |
} | |
/// <summary> | |
/// Raises the play button click event. | |
/// </summary> | |
public void OnPlayButtonClick () | |
{ | |
webCamTextureToMatHelper.Play (); | |
} | |
/// <summary> | |
/// Raises the pause button click event. | |
/// </summary> | |
public void OnPauseButtonClick () | |
{ | |
webCamTextureToMatHelper.Pause (); | |
} | |
/// <summary> | |
/// Raises the stop button click event. | |
/// </summary> | |
public void OnStopButtonClick () | |
{ | |
webCamTextureToMatHelper.Stop (); | |
} | |
/// <summary> | |
/// Raises the change camera button click event. | |
/// </summary> | |
public void OnChangeCameraButtonClick () | |
{ | |
#if UNITY_ANDROID && !UNITY_EDITOR | |
if (!webCamTextureToMatHelper.IsFrontFacing ()) { | |
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS; | |
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree); | |
} else { | |
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree); | |
} | |
#else | |
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing (); | |
#endif | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment