Unity+Vuforiaで「グリコぬりえ」っぽい何かをどう実現するか考えてみる【未完成】


## はじめに

[グリコぬりえ](http://web.glico.jp/dr2014/cp/g-nurie/index.html)というアプリがある。
リンク先を見てもらえればわかるが、グリコ製品についているオリジナル台紙に色を塗って、アプリを起動してスマホのカメラをかざすと、ARでドラえもんが表示され動く。
表示されたドラえもんは、塗った色や模様がそのまま反映されている。

では、このアプリと似たようなものを作る場合どうしたらよいのだろうか、というのが今回の記事の趣旨である。
最初にお断りしておくと、今のところ実際には実現していない（企画は持ち上がったが、（主に時間的理由で）お蔵入りしたので…）。

とはいえ、そこそこ考えたので忘れないように、その思考結果を記録しておく。

## 必要と思われる機能

必要な機能をあげていく。

・カメラに台紙がかざされたのを認識する。
・認識された画像から、塗り絵部分を切り取る。
・塗り絵画像を3Dモデルにテクスチャとして貼り付ける。

おそらく、こんなところ。

## カメラに台紙がかざされたのを認識する。

まずは、台紙を認識するところだが、これはUnity + Vuforia　で出来る。
以下の記事が参考になる。

[Unity + VuforiaでARに挑戦する](http://qiita.com/JunSuzukiJapan@github/items/14b14f9608b75bd325d8)



## 認識された画像から、塗り絵部分を切り取る。

VuforiaのARCameraから、なんとか塗り絵部分だけの画像を生成できないかといくつか試してみたがうまくいかなかった（良い方法があればご教授お願いしたいです）。

で、考えたのは、WebCamTextureを使う方法。
（Vuforiaと同じScene内で使うと動かない可能性もあるので試してみたが、問題なく動きそうだった。）

下記のようなコードでWebCamTextureを使って画像を取得してみると、カメラに写ったそのままの画像がとれるようだ（Vuforiaが認識したとこだけとるのはうまくいかなかった）。

```csharp:
// Vuforiaとは無関係なPlaneを配置して、それに貼って使ってみた。
using UnityEngine;
using System.Collections;

public class WebCameraTextureObject : MonoBehaviour {
	void Start () {
		WebCamDevice[] devices = WebCamTexture.devices;
		if(devices.Length > 0){
			Debug.Log ("devices = " + devices.Length);
			WebCamTexture webcamTexture = new WebCamTexture(320, 240, 12);
			renderer.material.mainTexture = webcamTexture;
			webcamTexture.Play();
		}else{
			Debug.LogError("no web cameras.");
		}
	}
}
```

あとは、このカメラ画像から、塗り絵部分を切り取りたいところだが、それにはあらかじめいくつかの仕込みが必要な気がする。

>この辺から、だんだんあやふやになっていきます。

### どうやって切り取るか？

改めて、グリコの台紙を見てみると、４隅に太い線でかぎかっこが描かれている。
おそらく、これを基準にして四角形に切り取っているのではないだろうか。

だとすると、OpenCVあたりの画像処理ライブラリを使って、４隅のかぎかっこを認識できれば四角形の４つの角が決まるので、それを使って画像を切り取れそうな気がする。

つまり、台紙側に４つの角を認識させるためのマーカーみたいなものを用意しておく必要がある（と思われる）。
マーカーを用意してしまえば、後はなんとかなるだろう。


### どうやって3Dモデルに貼る位置をあわせるか？

うまく塗り絵画像を取得できたとして、どうやって3Dモデルにずれずにピタッと貼れるだろうか。

>3Dモデリングには詳しくないので間違っているかもしれませんが、説明していきます。
>（間違いに気づいたかたはコメントお願いします。）

[初心者のための！作って学ぶBlenderの基礎：③マテリアル・テクスチャを設定する](http://nvtrlab.jp/column/2-3)
という記事をみると、3Dモデルに１枚の画像を貼り付けることで、色や質感などを表現しているようだ。

この記事中の「[テクスチャを描く](http://nvtrlab.jp/column/2-3#i-6)」という部分をみてほしい。
ここにある画像がUVテクスチャという3Dモデルに貼り付ける画像のようだ。動物の皮をはいで平らにしたらこんな感じになるのかもしれない。

さて、ここで考えてみたいのは、
・UVテクスチャと塗り絵の関係
である。

・塗り絵は、3Dモデルを二次元の絵で表現したものといえる
・UVテクスチャは、3Dモデルを切り開いて二次元にしたものといえる

厳密には違うかもしれないが、両者はほぼ似たような目的のものと言えるだろう。

ピンときた人もいると思うが、つまりは、塗り絵をそのままUVテクスチャとして貼れば、3Dモデルにピタっとあうように、あらかじめ書いておけばいいのである。
逆に言うと、3DモデルからUVテクスチャを作るときに、塗り絵にも使えるようにモデルの各パーツのテクスチャを配置する必要がある。

そして、「グリコぬりえ」アプリで言うと、タイムマシンなど一部にしか色を塗れないオブジェクトは、カメラが後ろに回り込めないようにしておく必要があるだろう。
ドラえもんは背中も色が塗れるので、動かしてもあまりおかしいことにはならないが、タイムマシンは動かしてはいけない。

3Dモデルを作るときには、以上を頭にいれながら、慎重に作成する必要がある。

>どうでもいいが、私にはそんな技術はないので、モデラーさんでも雇わないとこの手のアプリは作れない…。


### 結論のようなもの

・台紙と3Dモデルとの整合性が肝

台紙は3Dモデルを意識しながら作る必要があり、
3Dモデルは台紙を意識しながら作る必要がある。



## 塗り絵画像を3Dモデルにテクスチャとして貼り付ける。

詳細はまだ考えていないが、塗り絵部分を切り取れればなんとかなるんじゃないかと思う。

## さいごに

この考え方でうまくいった方はご報告いただけるとうれしいです。
うまくいかなかった方も歓迎です（出来れば解決方法つきだと２倍うれしいです）。


## 参考リンク

もしかすると参考になるかもしれないサイトをリンクしておく。

### ブログ等リンク

[[Unity][Unity3d]Unity 3.5の新機能、 WebCamTexture を使ってみた](http://d.hatena.ne.jp/nakamura001/20120107/1325922070)
[[Unity] WebCamTextureのカメラ動画をフルスクリーンで表示してみる](http://blog.be-style.jpn.com/article/55367421.html)
[Unity でカメラの映像を別ウィンドウ表示してみた](http://tips.hecomi.com/entry/2014/01/26/231144)
[Unityのオフスクリーンレンダリング](http://qiita.com/tsubaki_t1/items/ee8419c054d17ade32ee)
[Analysing colors of Image Target](https://developer.vuforia.com/forum/unity-3-extension-technical-discussion/analysing-colors-image-target)

### Unityドキュメントへのリンク

[Graphics.Blit](http://docs.unity3d.com/ScriptReference/Graphics.Blit.html)
[WebCamTexture.GetPixels](http://docs.unity3d.com/ScriptReference/WebCamTexture.GetPixels.html)
[Texture2D.SetPixels](http://docs.unity3d.com/ScriptReference/Texture2D.SetPixels.html)
[Camera.Render](http://docs.unity3d.com/ScriptReference/Camera.Render.html)