UnityでOpenCVを使う方法について調べました。
ネット上ではiOSだったり、C++からネイティブプラグインで使う方法はあったのですが、C#スクリプトから直に使う方法がありませんでした。前にOpenCvSharpを使ってやったのですが、うまくいかなかった経緯もあるので、再挑戦です。結果的にはOpenCvSharpで実現できました。なお、確認環境はWindowsのみです。
必要なものは次の2つです。OpenCVのバージョンに対応したOpenCvSharpを使用してください。今回は2.4.9でやっています。
作ったものはこちらに置いておきます。
事前にUnityのプロジェクトを作成しておきます。
それぞれ展開して、OpenCVの「opencv\build\x86\vc12\bin」にある「~249.dll」をUnityのフォルダ(Assetなどと同じ)にコピーします。「249」はOpenCVのバージョンなので読み替えてください。「~249d.dll」というdのついたものはデバッグ版なので、入れなくてよいです。めんどくさいので、全部入れちゃっても大丈夫です。
続いてOpenCvSharpです。OpenCvSharpExtern.dllのみ先ほどのOpenCVのDLLと同じフォルダにコピーします。
UnityエディタでAssetの下に「Plugins」というフォルダを作成し、「OpenCvSharp.dll」、「OpenCvSharp.CPlusPlus.dll」、「OpenCvSharp.Blob.dll」を入れます。「OpenCvSharp.UserInterface.dll」および「OpenCvSharp.Extensions.dll」はWindows FormsやWPFに使うので不要です。
Hierarchyに「Quad」と「Directional light」を置き、カメラに収まるように調整します。カメラのデフォルトが(おそらく)640x480なので、Gameの画面を4:3にしておくとよいでしょう。
Webカメラの画像を表示するために「WebCamera」というC#スクリプトを作成します。UnityではWebCamTextureという素敵なクラスがありますが、カメラのデータをいろいろ扱いたいのと、サンプルのためOpenCVのカメラ機能を使います。
コードはこんな感じです。やってることはコメントを見てください。
using UnityEngine;using System.Collections;
using OpenCvSharp.CPlusPlus;
using OpenCvSharp;
public class WebCamera : MonoBehaviour {
public int Width = 640;
public int Height = 480;
public int FPS = 30;
VideoCapture video;
public int VideoIndex = 1;
Texture2D texture;
// Use this for initialization
void Start () {
// カメラを列挙する
// 使いたいカメラのインデックスをVideoIndexに入れる
// 列挙はUnityで使うのはOpenCVだけど、インデックスは同じらしい
var devices = WebCamTexture.devices;
for ( int i = 0; i < devices.Length; i++ ) {
print( string.Format( "index {0}:{1}", i, devices[i].name ) );
}
// ビデオの設定
video = new VideoCapture( VideoIndex );
video.Set( CaptureProperty.FrameWidth, Width );
video.Set( CaptureProperty.FrameHeight, Height );
print( string.Format( "{0},{1}", Width, Height ) );
// テクスチャの作成
texture = new Texture2D( Width, Height, TextureFormat.RGB24, false );
renderer.material.mainTexture = texture;
}
// Update is called once per frame
void Update () {
using ( Mat image = new Mat() ) {
// Webカメラから画像を取得する
video.Read( image );
// Bitmap形式に変えてテクスチャに流し込む
using ( var cvtImage = image.CvtColor( ColorConversion.BgrToRgb ) ) {
texture.LoadRawTextureData( cvtImage.ImEncode( ".bmp" ) );
texture.Apply();
}
}
}
/// <summary>
/// 終了処理
/// </summary>
void OnApplicationQuit()
{
if ( video !=null ) {
video.Dispose();
video = null;
}
}
}
これを実行するとWebカメラの画像が表示されます(なぜか右端の画像が左端にいますが、、、)。
exeにするときは、先ほどUnityのフォルダ直下にいれたOpenCVのDLLとOpenCvSharpExtern.dllをexeと同じ場所にコピーすればOKです。