2022.8.14
UnityでYOLOを使うにはBarracudaという機械学習の推論ライブラリを使います。
https://docs.unity3d.com/Packages/com.unity.barracuda@3.0/manual/index.html
カスケード分類器による物体認識は前回の記事を参照ください。
『OpenCV plus Unityでカスケード分類器を使った物体認識 』
今回作るのはUnity上でYOLOを使ってWebカメラ画像で物体認識するサンプルです。
こちらの記事の通りにOpenCV plus Unityをインストールします。
UnityでOpenCV plus Unityを動かす環境構築
インストール方法はこちらです。
今回はGitHubからインストールします。Packages/manifest.json
に以下を追記します。
"com.unity.barracuda" : "https://github.com/Unity-Technologies/barracuda-release.git"
すると、Package Managerからインストールすることができます。
今回はこちらのサンプルを参考にしました。
https://github.com/keijiro/YoloV4TinyBarracuda
上記プロジェクトで使われているこちらのパッケージを自分のプロジェクトのPackagesの中に配置します。
https://github.com/keijiro/YoloV4TinyBarracuda/tree/main/Packages/jp.keijiro.yolov4tiny
新規にSceneを作成します。UI > CanvasのGame Objectを作成します。その中にRawImageを作成します。
RawImageのInspectorはこのようになります。CameraScalerというOpenCV plus Unityのスクリプトをアタッチします。InferenceYOLOというスクリプトをアタッチします。
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://github.com/SatoshiKawabata/Unity-Object-Detection/tree/main/Assets/YOLO Sample