1Click飲みRomoCartTempescope色色[:iroiro]Other Projects

2015年9月27日日曜日

子供の3D写真からポップアップカードを自動生成しよう

親バカ以外あまり共感できないであろう話をします。

僕はたまに子供の写真をKinectで撮影します。
そうするとこんな風に3Dで記録できるのでOculus Riftで没入したりできるのですが、
このままでは普通の写真みたいに机に飾れないという問題があります。

もちろん3Dプリンタを使えば立体的に印刷することも可能ですが、
今の印刷粒度ではこんな化物みたいになってしまい、子供を愛でるどころの騒ぎではなくなってしまいます。
また3Dプリンタで印刷すると高いし、印刷物は壊れやすい(ので郵送に気使う)し、持ち運びしにくいという問題もあります。
化物みたいになったAくん
「立体的に」「写真並の分解能を保って」「安く」立体画像を飾る方法はないのでしょうか?
こういうの。
これなら立体的ですし、紙の印刷物なので写真クオリティも出せるし、なにより安いですね。
更に畳めば財布に入れておいたり、封筒で実家に送ったりすることもできます。
そこで今回はKinectで撮影した3D点群データから、自動的にポップアップカードを生成するプログラムを作ってみました。

やり方

1. 子供をKinectで撮影する。
 こんな感じの点群が取れます。子供じゃなくて猫とかでもいいです。


2. 点群をクラスタリングして数枚のレイヤーに分ける
元の点群データのままでは面ではないので紙に印刷することはできません。
近い点同士を集めて面状に整形する必要があります。

ここはいろんな方法が考えられますが、今回は超簡易的にカメラからの距離によって(k-meansで)クラスタリングすることで面に分ける、ということを行います。
点群データをカメラからの距離毎に点のヒストグラムにすると、以下図のように人・物・壁の位置にピークが立ちます。

元の点群データを横から見た図(上)と、各距離にある点の数(下)
これを簡単のためとりあえず2クラスタに分けてみるとこんな感じで、距離的に近い点同士が大体同じレイヤにまとまるようにクラスタリングされます。
近い面と遠い面に分かれました
3. 1枚のカードに結合する
で、各レイヤーを一枚の面上に結合し、切り抜き方を計算します。
以下図のように、レイヤーを少しずつ段差をずらして一枚の紙上に結合し、切り抜き線を計算して赤線を引きます。
(この際、最終的なカードがちゃんと自立するようにレイヤーを綺麗にする処理がありますが、面倒なので説明を割愛します。)
赤い点線を切り抜くとレイヤーが切り出される。
こんな感じで、1枚のカードを切り抜くと各レイヤーが立体的に現れる構造が作られます。
 これはシミュレーションのCGですが・・・

4. 実際に印刷してみる
実際に印刷してみました。

完成。かわいい。
大量生産できます。
ちょっと(元がKinectなので)画質が雑ですが、立体ならではの躍動感があります。

まとめ

今回はKinectから取得した点群データに基づき、ポップアップカードを自動生成するアルゴリズムを作り、実験してみました。
3Dプリンタよりも写真に近い画質で立体感を維持したまま、卓上に飾ることのできるディスプレイを作ることができました。
これなら子供の写真をバシバシ写真撮ってガンガン印刷して飾れます。

・Kinectで撮影するのは少し一般向けにはハードルが高いですが、最近は市販の3Dデジカメもあります。また、平面画像からでもオブジェクト認識してレイヤー分けしたりできるかもしれません。

・僕は自分の子供の写真を会社の机に飾りたいという気持ちだけで作りましたが、例えば家族写真を封筒に入れて送ったり、財布に入れておいたりできるという便利さもあります。

・面倒なのでサービスにしてないですが、ポップアップカード作って欲しいという人がいたらご連絡ください。

子供の写真を3Dで残してないのはもったいないぞ!

0 件のコメント:

コメントを投稿