UnityでOpenCVを使いたい.UnityのNative Plug-insを使って,C++のOpenCVのDLL経由でOpenCVをUnityから呼び出す方法を取った.
UnityでOpenCVを使う方法
実装方法の候補
ざっと調べたところ,以下の3つの方法がよく知られているようだった.
- Asset StoreでOpenCV for Unity等の有料のものを購入する
- 利点:すぐに使える(試していないので確約はできない)
- 欠点:有料,メンテナンスされなくなったら終了
- OpenCVSharpを使う
- 利点:無料,すぐに使える(同上)
- 欠点:Unityでは上手くいかないかも,と書いてある
- Native Plug-insを利用する
- 利点:無料,OpenCV以外への応用も可能(と思われる)
- 欠点:導入方法がよく分からない
手順
ということで,Native Plug-insを使う方法を調べてみることにした.実装手順としては,以下を考えている.
まずは,確実に動くであろう自作のC++のDLLをUnity上で使い,インストール済みのOpenCVのDLLをUnityで使ってみようという作戦だ.
実装環境
- Windows 10 64-bit
- Unity 2019.1.11f1
- OpenCV 4.1.1
- Visual Studio 2017
C++のDLLを作ってUnityで使う
C++のDLLを作る
手順は以下の通り.
- Visual StudioでDLL用プロジェクトを作成
File > New > ProjectでNew ProjectWindowを表示- そして
Visual C++ > Windows Desktop > Dynamic-Link Library (DLL)を選択 - プロジェクト名がDLLの名前になるので,分かりやすいよう
CppPluginsとした
CppPlugins.hとCppPlugins.cppを作成- コード自体は下記参照
- ファイル名は何でもいいです
- Releaseモードでx86とx64の2つのプラットフォームでビルド
Releaseとx64/ReleaseフォルダにCppPlugins.dllが作成されているはず
必要なコード
// // CppPlugins.h // #pragma once #ifdef CPPPLUGINS_EXPORTS #define CPP_API __declspec(dllexport) #else #define CPP_API __declspec(dllimport) #endif extern "C" { CPP_API int Add(int x, int y); }
// // CppPlugins.cpp // #include "stdafx.h" #include "CppPlugins.h" CPP_API int Add(int x, int y) { return x + y; }
作成したC++のDLLをUnityで使う
- Unity 3Dのプロジェクトを新規作成
Assets/Plugins/x86フォルダとAssets/Plugins/x64フォルダを作成- 作成したC++のDLLを対応するプラットフォームのフォルダにコピー
Releaseとx64/ReleaseのCppPlugins.dllをそれぞれAssets/Plugins/x86フォルダとAssets/Plugins/x64フォルダへ
- C#でプラグインを書く
- コード自体は下記の
CppPlugins.csを参照
- コード自体は下記の
- GameObject(何でもよい)から読み込み
- コード自体は下記の
PluginTest.csを参照
- コード自体は下記の
- 実行
必要なコード
// // CppPlugins.cs // using System.Runtime.InteropServices; public class CppPlugins { [DllImport("CppPlugins")] public static extern int Add(int x, int y); }
// // PluginTest.cs // using UnityEngine; public class PluginTest : MonoBehaviour { void Start() { Debug.Log("Add(1, 2): " + CppPlugins.Add(1, 2)); } }
Unityでの設定

実行結果
Add(1, 2): 3 UnityEngine.Debug:Log(Object) PluginTest:Start() (at Assets/PluginTest.cs:8)
OpenCVのC++のDLLをUnityで使う
自作DLLと同様の手順で進める.OpenCVのDLLはビルド済で,x86とx64アーキテクチャのDLLがあるものとする.OpenCVのビルドは色々と参考になるページがあるので別途参考のこと.
C++のDLLを更新
C++のDLLを作るで作成したVisual Studioのプロジェクトに以下の2つのコードを追加してビルドし,DLLを更新する.OpenCVへのリンクを忘れずに!
// // CvPlugins.h // #pragma once #ifdef CPPPLUGINS_EXPORTS #define CV_API __declspec(dllexport) #else #define CV_API __declspec(dllimport) #endif extern "C" { CV_API int cvAdd(int x, int y); }
// // CvPlugins.cpp // #include "stdafx.h" #include <opencv2/opencv.hpp> #include "CvPlugins.h" CV_API int cvAdd(int x, int y) { cv::Mat xMat(1, 1, CV_32S); cv::Mat yMat(1, 1, CV_32S); xMat.at<int>(0, 0) = x; yMat.at<int>(0, 0) = y; // 無理やりcv::Matを使って足し算してみる cv::Mat zMat = xMat + yMat; return zMat.at<int>(0, 0); }
自作のDLLとOpenCVのDLLをUnityに導入
- Unity内でDLLを更新
- C#でプラグインを書く
- 先の
CppPlugins.csに追記 - 下記参照
- 先の
- GameObject(何でもよい)から読み込み
- 先の
PluginTest.csに追記 - 下記参照
- 先の
- 実行
更新したコード
// // CppPlugins.cs // using System.Runtime.InteropServices; public class CppPlugins { [DllImport("CppPlugins")] public static extern int Add(int x, int y); [DllImport("CppPlugins")] // added public static extern int cvAdd(int x, int y); }
// // PluginTest.cs // using UnityEngine; public class PluginTest : MonoBehaviour { void Start() { Debug.Log("Add(1, 2): " + CppPlugins.Add(1, 2)); Debug.Log("cvAdd(3, 5): " + CppPlugins.cvAdd(3, 5)); // added } }
Unityでの設定

実行結果
Add(1, 2): 3 UnityEngine.Debug:Log(Object) PluginTest:Start() (at Assets/PluginTest.cs:8) cvAdd(3, 5): 8 UnityEngine.Debug:Log(Object) PluginTest:Start() (at Assets/PluginTest.cs:9)