ブログ@kaorun55

HoloLensやKinectなどのDepthセンサーを中心に書いています。

UnityでOpenCVを使う(Windowsアプリ)

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のついたものはデバッグ版なので、入れなくてよいです。めんどくさいので、全部入れちゃっても大丈夫です。

スクリーンショット_101614_034839_PM

続いてOpenCvSharpです。OpenCvSharpExtern.dllのみ先ほどのOpenCVのDLLと同じフォルダにコピーします。

スクリーンショット_101614_034908_PM

UnityエディタでAssetの下に「Plugins」というフォルダを作成し、「OpenCvSharp.dll」、「OpenCvSharp.CPlusPlus.dll」、「OpenCvSharp.Blob.dll」を入れます。「OpenCvSharp.UserInterface.dll」および「OpenCvSharp.Extensions.dll」はWindows FormsやWPFに使うので不要です。

スクリーンショット_101614_035009_PM

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 );

// OpenCVのデータがBGRなのでRGBに変える

// 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です。