UnityでYOLOを使った物体認識

2022.8.14

UnityでYOLOを使うにはBarracudaという機械学習の推論ライブラリを使います。

https://docs.unity3d.com/Packages/com.unity.barracuda@3.0/manual/index.html

カスケード分類器による物体認識は前回の記事を参照ください。

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

Webカメラで物体認識するサンプル

今回作るのはUnity上でYOLOを使ってWebカメラ画像で物体認識するサンプルです。

  1. OpenCV plus Unityをインストールする
  2. Barracudaをインストールする
  3. YOLO v4のパッケージをインストールする

OpenCV plus Unityのインストール

こちらの記事の通りにOpenCV plus Unityをインストールします。

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

Barracudaのインストール

インストール方法はこちらです。

https://github.com/Unity-Technologies/barracuda-release/blob/release/2.3.1/Documentation~/Installing.md

今回はGitHubからインストールします。Packages/manifest.jsonに以下を追記します。

"com.unity.barracuda" : "https://github.com/Unity-Technologies/barracuda-release.git"

すると、Package Managerからインストールすることができます。

https://user-images.githubusercontent.com/1194571/184496801-54422b1d-286a-4435-962d-8d2a48fdc3c3.png

YOLO v4パッケージのインストール

今回はこちらのサンプルを参考にしました。

https://github.com/keijiro/YoloV4TinyBarracuda

上記プロジェクトで使われているこちらのパッケージを自分のプロジェクトのPackagesの中に配置します。

https://github.com/keijiro/YoloV4TinyBarracuda/tree/main/Packages/jp.keijiro.yolov4tiny

Sceneを作成

新規にSceneを作成します。UI > CanvasのGame Objectを作成します。その中にRawImageを作成します。

https://user-images.githubusercontent.com/1194571/184541128-e5c24052-c4c5-4f4b-b797-01bd0938c259.png

RawImageの作成

RawImageのInspectorはこのようになります。CameraScalerというOpenCV plus Unityのスクリプトをアタッチします。InferenceYOLOというスクリプトをアタッチします。

https://user-images.githubusercontent.com/1194571/184541389-179d5b81-2e3a-4ea7-8fcf-f4b3cdee972a.png

InferenceYOLO.csはこのようになります。SurfaceにはRawImageをアタッチします。Resourcesにはjp.keijiro.yolov4tinyパッケージののYoloV4Tiny.assetをアタッチします。Markerには物体認識した箇所に表示させるマーカーのPrefabをアタッチします。

using System.Collections;
using System.Collections.Generic;
using OpenCvSharp;
using OpenCvSharp.Demo;
using UnityEngine;
using YoloV4Tiny;

public class InferenceYOLO : WebCamera
{
    [SerializeField, Range(0, 1)] float _threshold = 0.5f;
    [SerializeField] YoloV4Tiny.ResourceSet _resources = null;
    [SerializeField] Marker _markerPrefab = null;

    ObjectDetector _detector;
    Marker[] _markers = new Marker[50];

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

        _detector = new ObjectDetector(_resources);
        for (var i = 0; i < _markers.Length; i++)
        {
            _markers[i] = Instantiate(_markerPrefab, this.transform);
        }
    }

    protected override bool ProcessTexture(WebCamTexture input, ref Texture2D output)
    {
        _detector.ProcessImage(input, _threshold);

        var i = 0;
        foreach (var d in _detector.Detections)
        {
            if (i == _markers.Length) break;
            _markers[i++].SetAttributes(d);
        }

        for (; i < _markers.Length; i++)
        {
            _markers[i].Hide();
        }

        output = toTexture2D(input);
        return true;
    }

    private Texture2D toTexture2D(Texture tex)
    {
        var sw = tex.width;
        var sh = tex.height;
        var format = TextureFormat.RGBA32;
        var result = new Texture2D(sw, sh, format, false);
        var currentRT = RenderTexture.active;
        var rt = new RenderTexture(sw, sh, 32);
        Graphics.Blit(tex, rt);
        RenderTexture.active = rt;
        var source = new UnityEngine.Rect(0, 0, rt.width, rt.height);
        result.ReadPixels(source, 0, 0);
        result.Apply();
        RenderTexture.active = currentRT;
        return result;
    }
}

実行

実行するとWebカメラの映像で物体認識できるのがわかります。試しに犬を映してみるとCatかDogと認識されました。

https://user-images.githubusercontent.com/1194571/184557874-5221c8e2-dc17-4e25-90dc-da73879b83f1.gif

サンプルプロジェクト

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

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

© 2019-2022 kwst.site.