Hatena::ブログ(Diary)

備忘録 このページをアンテナに追加 RSSフィード Twitter

2013-12-30

UnityとiPhoneとOpenCVでなにかやる

22:29 | UnityとiPhoneとOpenCVでなにかやるを含むブックマーク UnityとiPhoneとOpenCVでなにかやるのブックマークコメント

iPhoneアプリ作ってみたい

Unityってどうなんだろ

ARっていったらOpneCVだよね

っていう短絡的な考えのもと

Unity@iPhoneOpenCVを使えないかここ数日取り組んでいます。

結果的に言うと

Unity@iPhoneOpenCVを使うならばNativePluginでやるしかないっぽいです。

UnityOpenCVを使うのであれば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スクリプトを追加
    1. 画面左の一覧からPlaneを選択
    2. 画面右のInspectorでAdd Component
    3. 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へのビルド設定をする
    1. File->Build Settingsを選択
    2. 上部のAdd Currentで今のSceneを追加します
    3. 画面下のPlatformでiOSを選択します。
    4. この時Development Buildにチェックを入れてください
iOSへBuildする

Build and RunをクリックするとXcodeが立ち上がります。

このままでは動かないので更に設定が必要です

ビルドにコケても驚かないでください。

Frameworkを追加する

Unity-iPhone.xcodeprojをクリックBuild Phasesで Link Binary with Libraries

opencv2.framework(作成方法は参考URLへ)

libc++.dylibを追加

これでビルドができます。

あと dSYMの作成に時間かかりまくるので

Build Settings Debug Information FormatでDWARFだけにしておくと早いです。

まとめ

Class

Planeに追加したスクリプトのファイル名

Plugins/iOS内においた.cppファイルのファイル名

はいずれも同じにしてください

大文字小文字もあります。