UnityとiPhoneとOpenCVでなにかやる
iPhoneアプリ作ってみたい
Unityってどうなんだろ
ARっていったらOpneCVだよね
っていう短絡的な考えのもと
Unity@iPhoneでOpenCVを使えないかここ数日取り組んでいます。
結果的に言うと
Unity@iPhoneでOpenCVを使うならばNativePluginでやるしかないっぽいです。
UnityでOpenCVを使うのであればOpenCVSharpっていうOpneCVのC#用ラッパーを使うのが一般的みたいなんですけど、
dylibを認識してくれないorビルドが通らなくなるってことで
とりあえずNativePluginでやってくことにしました。
以下のページを参照しました。
UnityでOpenCVを使う(iOS編)
とりあえずUnityで新規プロジェクト作成からのメモ書きを以下にしておきます。
Unityで新規プロジェクト作成
Planeを追加
Game Object -> Create Other -> Plane
Directional Lightを追加
Game Object -> Create Other -> Directional Light
Planeにスクリプトを追加
-
- 画面左の一覧からPlaneを選択
- 画面右のInspectorでAdd Component
- New Scriptを選択 imageProcessingとか名前をつけておきます。
なおこの時Planeの位置を(上部Transform内Position)を0 0 0ぐらいにしておきます。
カメラは右下のプレビューでPlane全体が映る程度にしたほうがいいです。
あと今回はiPhone5で行いました。Xを90度回転とかさせたほうがいいかもです。
とりあえずiPhoneの画面に映るものというのはCameraの設定で弄れるとおぼえておいてください
スクリプトで処理をした結果をPlaneのテクスチャに反映させ、それをカメラで映し出しています。
スクリプトの編集
AssetsフォルダにimageProcessing.csが表示されていると思います
それをダブルクリックするとMonoDevelopperが表示されるので
下記に編集してください
using UnityEngine; using System.Collections; using System.Runtime.InteropServices; public class imageProcessing : MonoBehaviour { [DllImport ("__Internal")] private static extern void UpdateTexture(System.IntPtr colors, int width, int height); WebCamTexture webcamTexture; Texture2D texture = null; // Use this for initialization void Start () { WebCamDevice[] devices = WebCamTexture.devices; if (devices.Length > 0) { webcamTexture = new WebCamTexture(devices[0].name ,320, 240, 10); webcamTexture.Play(); } } // Update is called once per frame void OnGUI() { Color32[] pixels = webcamTexture.GetPixels32(); GCHandle pixelsHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned); UpdateTexture(pixelsHandle.AddrOfPinnedObject(), webcamTexture.width, webcamTexture.height); if (texture) Destroy(texture); texture = new Texture2D(webcamTexture.width, webcamTexture.height); texture.SetPixels32(pixels); texture.Apply(); pixelsHandle.Free(); renderer.material.mainTexture = texture; } }
iPhone5 でいうとdevices[0]が背面のカメラ devices[1]が全面のカメラになります
print(devices[i].name)とかして確認して下さい
解像度は320x240で10FPSをターゲットとして要求します。
NativePluginの作成
Assetsの中にPlugins/iOSフォルダを作成します(ここにおいておくとXcode起動時に自動で入れてくれるらしいです。)
その中にPlaneに設定したスクリプト名と同名のファイルを作成します。
今回はimageProcessing.csなのでimageProcessing.cppになります。
中身は以下のようにしてください
#ifdef __cplusplus #import <opencv2/opencv.hpp> #endif extern "C" { void UpdateTexture(char* data, int width, int height); } void UpdateTexture(char* data, int width, int height) { IplImage* p = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 4); cvSetData(p, data, p->widthStep); IplImage* g = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); cvCvtColor(p, g, CV_RGBA2GRAY); cvCanny(g, g, 50.0, 200.0); cvCvtColor(g, p, CV_GRAY2RGBA); cvReleaseImageHeader(&p); cvReleaseImage(&g); }
ここまで設定ができればあとはビルドです。
iOSへのビルド設定をする
-
- File->Build Settingsを選択
- 上部のAdd Currentで今のSceneを追加します
- 画面下のPlatformでiOSを選択します。
- この時Development Buildにチェックを入れてください
Frameworkを追加する
Unity-iPhone.xcodeprojをクリックBuild Phasesで Link Binary with Libraries
opencv2.framework(作成方法は参考URLへ)
libc++.dylibを追加
これでビルドができます。
あと dSYMの作成に時間かかりまくるので
Build Settings Debug Information FormatでDWARFだけにしておくと早いです。