OpenCV plus Unityでカスケード分類器を使った物体認識

2022.8.14

OpenCV plus Unityを使った物体認識をやってみました。今回は顔認識のカスケード分類器を適用しました。

OpenCV plus Unityの環境設定は前回の記事にまとめてあります。

『UnityでOpenCV plus Unityを動かす環境構築 』

OpenCV plus Unityでカスケード分類器を使う

OpenCV plus Unityでカスケード分類器を使うにはOpenCvSharpのCascadeClassifierクラスを使います。

↓CascadeClassifierはこちらのクラスになります。

https://github.com/shimat/opencvsharp/blob/master/src/OpenCvSharp/Modules/objdetect/CascadeClassifier.cs

Sceneを作成

今回はWebカメラに映る顔を認識するプログラムを作成します。

OpenCV plus Unityの環境構築を行ったら、Assets > Scenes に SampleScene というSceneがあります。これを今回は使います。

Assets > OpenCV + Unity > DemoLiveSketch_WebCamを起動してCanvasとRawImageをコピーします。これをSampleSceneにペーストします。

https://user-images.githubusercontent.com/1194571/184542597-57a8b099-1473-4d60-8df3-a915ebea6afa.png

Live Sketch Scriptコンポーネントを削除します。新たに CascadeRecognizer.cs スクリプト作成し、アタッチします。

https://user-images.githubusercontent.com/1194571/184542606-e10a0288-5db9-47cd-91d6-b64b9a9d8511.png

ソースコード

CascadeRecognizer.csのソースコードはこちらです。先程のコンポーネントで、FacesにはAssets/OpenCV+Unity/Demo/Face_Detector/haarcascade_frontalface_default.xmlを、SurfaceにはRawImageをアタッチします。

このhaarcascade_frontalface_default.xmlというファイルがカスケード分類器になります。

namespace OpenCvSharp.Demo
{
    using UnityEngine;

    public class CascadeRecognizer : WebCamera
    {
        public TextAsset faces;
        private CascadeClassifier cascadeFaces;

        protected override void Awake()
        {
            base.Awake();

            // classifier
            FileStorage storageFaces = new FileStorage(faces.text, FileStorage.Mode.Read | FileStorage.Mode.Memory);
            cascadeFaces = new CascadeClassifier();
            if (!cascadeFaces.Read(storageFaces.GetFirstTopLevelNode()))
            {
                throw new System.Exception("FaceProcessor.Initialize: Failed to load faces cascade classifier");
            }
        }

        protected override bool ProcessTexture(WebCamTexture input, ref Texture2D output)
        {
            Mat image = Unity.TextureToMat(input);
            Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);
            Mat equalizeHistMat = new Mat();
            Cv2.EqualizeHist(gray, equalizeHistMat);
            OpenCvSharp.Rect[] rawFaces = cascadeFaces.DetectMultiScale(gray, 1.1, 6);
            foreach (var faceRect in rawFaces)
            {
                Cv2.Rectangle((InputOutputArray)image, faceRect, Scalar.LightGreen, 2);
            }
            output = Unity.MatToTexture(image);
            return true;
        }
    }
}

実行

このように顔が認識されます。haarcascade_frontalface_default.xmlのファイルは今回は顔認識でしたが、別の物体認識用のファイルを作成して適用すれば、別の物体認識ができるようになります。

https://user-images.githubusercontent.com/1194571/184542663-83ea72f3-f507-4c6b-956a-876e109468b8.gif

サンプルプロジェクト

今回のサンプルプロジェクトはこちらのリポジトリに置いてあります。

https://github.com/SatoshiKawabata/Unity-Object-Detection/tree/main/Assets/Cascade Sample

© 2019-2022 kwst.site.