見出し画像

[開発日記]『2つの壁の貫通する仮想的な穴(ウソ穴)をAR(拡張現実)で作る』まで

はじめに

このデモ動画が撮れるまでの開発記録です。構想から実現まで1年以上かかりました。

ーーーーーーーーーーーーーーー

ここから時系列で開発状況を記載します。

(2020/09/18) 目標設定→構成検討

目標『2つの壁の貫通する仮想的な穴(ウソ穴)をAR(拡張現実)で作る

これまでは1つの壁に対してウソ穴が作れました。次バージョンでは縦にならんだいくつもの壁に仮想的な穴をあけられる、新ロジックのウソ穴の開発をはじめました。

これまでは AR.js と A-Frame を使ってウソ穴を開発していました。今回も使うつもりでした。ですがこれら技術では、ARマーカーの検出を複数実行など今までより込み入った処理の実装が難しいと考え、使用を断念しました。

AR.js + A-Frame では厳しい。ではどうするか…
調べたところ OpenCV でもARができることを知りました。

ここから、OpenCVの調査を開始しました。

(2021/01/24) OpenCV で WebAR 成功

OpenCVを使った、超基本のARができました。これをWebサイトにしたいと思いました。

OpenCVでARを実装する方法は見つかるのですが、それをWebサイトとする方法がみつからず…仕方なく試行錯誤を繰り返し、ようやくWebARが出来ました。


(2021/07/11) 2つの壁を貫通するウソ穴の開発に成功

OpenCVを使い2壁貫通に成功したデモ動画です。1つ目のARマーカー上に作ったウソ穴があります。そのウソ穴から見える2つ目のARマーカーにもウソ穴があります。

↓ は苦戦中の動画です。2つ目のARマーカーにウソ穴が出現しなくて、困ってました。

苦労しましたが、ようやく2つの壁を貫通する方法ができました。でもこれでは "穴" という感じがありません。穴っぽくするには凹みが必要です。

ということで、ここから 凹むARの開発 が始まります。


(2021/08/29) OpenCVを調べる

凹むARの前に、普通のAR(凹まないAR)ができる方法を調査します。
手始めにOpenCVでできることでウソ穴に使えそうな機能を調査しました。調査結果はこちら ↓

調査がひと段落したので凹むARの開発に取り掛かろうとしたところ、調査した機能だけでは不足していることが判明しました。"不足していたこと" それは "画像の変換" 。ARマーカーの形状に合わせて画像の形状を変換する機能の調査が不足してました。

"画像の形状変換" これはアフィン変換というらしく、OpenCVにはその機能がありました。アフィン変換の調査内容についてQiitaに投稿していませんが、以下などのサイトで勉強させて頂きました。

※余談:身近?なアフィン変換
ホワイドボードを撮影した画像の歪み修正などに使われるそうです

画像7



(2021/09/06) アフィンじゃなくてロドリゲスだった

アフィン変換をあれこれ調べると次元の壁に阻まれました。
アフィン変換は、2次元座標(X,Y軸)上の変換のようで、3次元座標(X,Y,Z軸)上の変換方法が見つけられませんでした。そんなとき見つけたのがロドリゲスの回転公式でした。

ロドリゲスの回転公式の数式は理解できなかったのですが、OpenCVが用意してくれたestimatePoseSingleMarkers(),projectPoints()のおかげで問題なく使用できました。

AR処理する元画像がこちらです ↓

画像7

AR処理で、立方体の座標をARマーカーの上に乗せるとこのようになります。

画像6

更にARマーカーの上に乗った立方体に画像を張り付けることに成功しました。

画像5

仕組みを簡単に説明します。
(Fig-1)の向かって左が3次元空間に配置したARマーカー、向かって右がカメラで撮影した映像です。

画像9

(Fig-1) 3次元空間のARマーカーとカメラ映像

(Fig-2)は、(Fig-1)の3次元空間に配置したARマーカーに対しカメラの撮影位置を算出した結果を図示したものです。
カメラで撮影した映像から3次元空間に配置したARマーカーを撮影したカメラ位置の算出には、estimatePoseSingleMarkers()を使用します。
正確には、ARマーカーとカメラ位置の相対的な位置関係を算出します。原点(0,0,0)はARマーカーの中点のようです。

画像9

(Fig-2) カメラ位置の算出

ここまでで、(Fig-3)のように撮影したARマーカーの映像からカメラ位置が算出できました。

画像10

(Fig-3) 算出されたカメラ位置

ここからは立方体に対する処理になります。
(Fig-4)は、向かって左が3次元空間に配置した立方体、中央のカメラがさきほどestimatePoseSingleMarkers() で算出したカメラの位置、向かって右がそのカメラで撮影した映像です。
算出したカメラ位置から立方体を撮影するとどのような座標になるかを projectPoints() で算出します。

画像11

(Fig-4) 3次元空間の立方体とカメラとカメラ映像

(Fig-5)のように立方体の底面がARマーカーと一致するようにしています。

画像12

(Fig-5) ARマーカーと立方体

3次元の立方体をARマーカーに沿うように描画するテストについて、ここまででてきたこと

<できたこと>
・立方体の8つの頂点に円を描画
・立方体の底面とARマーカーが一致するように描画
・立方体の1つの側面に画像を描画

追加したい機能はこちら

<追加したい機能>
・カメラ映像に対応したい
・立方体の各面について、描画する順序を判定したい

・カメラ映像に対応したい
 →静止画内のARマーカーに対しAR処理を実装してきましたが、カメラ映像には対応していません。
・立方体の各面について、描画する順序を判定したい
 →立方体の6つの面について、どの面が手前なのか奥なのかの判定がありません。そのため6つの面に画像は配置すると、立方体にみえない形になります。

ここから、追加したい機能を追加していきます。


(2021/09/07) カメラ映像に対応

これまで静止画でしか対応できていませんでしたが、カメラ映像に対応できるようにしました。


(2021/09/11) 立方体の6面の "奥/手前" を判定

立方体の6つの面について、どの面が手前なのか奥なのかの判定方法の検討を開始しました。最初は紙に絵をかいて、あれでもないこれでもないと判定方法を検討していました。

画像6

絵を描いていると訳が分からなくなったため、立方体の模型をつくりました。やはり立体は、2次元(紙)でなく3次元で考える方が分かりやすかったです。

画像3

具体的な判定方法は割愛しますが、なんとか判定する方法ができました(大変でした)。判定方法ができたため、立方体の6面全てに画像を張ることができるようになりました。

これで普通のAR(凹まないAR)ができました。

次は、凹むAR の開発です。


(2021/09/12) 凹むAR

普通のAR(凹まないAR)ができたので次に凹むARを開発しました。詳細は割愛しますが、ARで描画された映像が凹んだように見えるよう画像処理しました。凹む仕組みについてさらっと書きましたがネットで情報が見つけられず方法論の検討から実装まで苦労しました。


(2021/10/14) 1つの壁に対応した"ウソ穴"の完成

完成した凹むARと、ストリーミング配信を組み合わせてウソ穴をつくりました。

凹むARで描画した立方体の底面をストリーミング配信の映像にしています。板の裏側にカメラが付いたラズベリーパイがあり、ストリーミング配信しています。

画像6

ここまでくればあと少し、2つの壁にウソ穴を出現させ縦に並んだ壁を貫通するように仮想の穴をあけられるようにします。


(2021/10/16) 完成! 2つの壁を貫通するウソ穴

2つの壁にウソ穴を出現させ縦に並んだ壁を貫通するように仮想の穴をあけました。

これは、AR処理を複数回実行することで実現しました。AR処理を複数実行したことで処理量が増えてしまい、デモ動画がコマ落ちしました。映像がカクカクしてるのはそのせいです。

これからについて

2つの壁を貫通するウソ穴ができました。ですがこれで完成ではありません。2壁貫通のウソ穴ができた後、このウソ穴をWebAR(Webサイトにアクセスすると利用できるウソ穴)にしたのですが、スマホでは処理がおいつかず大変なコマ落ちが起きてしまいました。まだまだ、改善の余地があります。

『街中で使えるウソ穴』これを目指しウソ穴の開発は続きます。


こんな弱小ブログでもサポートしてくれる人がいることに感謝です。