RICOH THETAで自動撮影しLINEに半自動でアップロードするカメラ、『Selfie THETA』


先日、友人の結婚式のデジタル演出プロジェクトを行いました。我ながらかなりイケてると思うのでぜひ読んでほしいです。

- [参列者みんなが「主役」になる、おもてなし披露宴をテクノロジーで支えた話](https://note.mu/kokuhaku_2/n/n4decda35aef8)



そのなかで、デジタル上のコンテンツだけではなく、一部、リアル空間に設営するタイプのハードウェアプロダクトも作成しました。
顔検出技術を使って参列者を検出し、360度カメラのRICOH THETAのシャッターを自動で切り、LINEグループに投稿しみんなでシェアするカメラ**「Selfie THETA」**です。



RICOH THETAは大好きなんですが、欠点として

- THETAを持っている人しか撮影できない
- 撮った360度画像の共有が不便

というのがあります。



これらを改善して、

- THETAを誰でも使えるように会場に設置し、撮影方法がわからない人でも本体に触ることなく撮影ができる
- 撮影した写真はグループLineへ投稿され、複数人と手軽に360度ビューを共有する

というのを目指しました。セルフで撮影できるTHETAということで、**「Selfie THETA」**です。


![selfie-theta.jpg](https://qiita-image-store.s3.amazonaws.com/0/100780/1ad861bb-605b-7e5d-ab2f-8a616888e5ef.jpeg)
(時間なさすぎて見た目がダサい...)


完成品の挙動として、実際に顔検出を行いシャッターを切る様子は[こちら](https://youtu.be/9qGCU4JGQhc)です。
（音声ガイドには、声優スクール所属の方に声を当ててもらいました）

(クリックするとyoutubeに飛びます)
[![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/9qGCU4JGQhc/0.jpg)](https://www.youtube.com/watch?v=9qGCU4JGQhc)



撮影した360度画像は"半自動"でLINEへ投稿されます。

LINEアプリでは、投稿された画像が360度画像かどうかを自動で識別し最適なビューに切り替えてくれるので、グループ上に投稿された360度画像を参加者全員でシェアし閲覧することができます。

![line_theta.png](https://qiita-image-store.s3.amazonaws.com/0/100780/325afde1-db60-815a-c4e3-6311559ad6e1.png)

![theta_merge.png](https://qiita-image-store.s3.amazonaws.com/0/100780/b03c5c73-c036-6638-c97f-9cb92492e0a3.png)



## 使用デバイス

- RaspberryPi 3（処理の本体）
- [RICOH THETA SC（カメラ本体）](https://amzn.to/2NU2MIh): 360度画像撮りたいだけならSCシリーズで問題ない。2万円ほど。
- [webカメラ（顔認識用カメラ）](https://amzn.to/2QJinJ0): 広角カメラが欲しかったので購入したが、もっと簡易のwebカメラでも問題ない。
- RaspberryPi用小型モニター（顔認識状態の確認）: 特になければ無いでok。式場のようにモニター接続ができない環境では便利。
- [小型スピーカー](https://amzn.to/2QIcZGa): 小型なのにかなり大きな音がでる。値段もリーズナブルで普段遣いにもおすすめ。
- [大型の外部バッテリー](https://amzn.to/2NYkTN2): 20000mAhくらいの大容量のものを1本持っておくと、RasPiとTHETAの給電を余裕で一日賄えます。取り回しも楽になるので便利。
- [三脚](https://amzn.to/2QLwFZS): 比較的しっかりしていてコスパも良い三脚。
- （おまけ）[THETA用エクステンション](https://amzn.to/2MOqzEH): THETAを三脚に指したまま給電するにはこういうものが必要。ふざけた値段だが、急がば回れで結局一番こいつがしっかりしている。正直デフォの付属品としてほしい。

という感じです。



## コード

GitHubにすべて公開しています。Python3です。

- https://github.com/ysdyt/Selfie-Theta



## 処理の流れ

大きな処理の流れは以下です。

1. RaspberryPiに接続されたwebカメラで顔認識を行う
2. 顔認識が行われたら音声ガイダンスを流して写真を自動撮影する
3. 撮影した画像をDropbox APIで所定のフォルダに格納する
4. スマホアプリのWorkflowで半自動で画像をLINEへ投稿する



各処理について苦労した点など簡単に書きます。



## 1. RaspberryPiに接続されたwebカメラで顔検出を行う

RaspberryPiに接続されたwebカメラで、カメラの前に立った人の顔検出を行い、カメラのシャッターを自動で切る処理を行います。ユーザーはカメラに物理的に触る必要はありません。

以前に同様の処理を行うおもちゃを作ったことがあったので顔検出周りはこちらのコードを再利用しています。

- [クリスマスツリーに自動セルフィー機能を付けて会社のクリスマス会に設置してみた話](https://qiita.com/ysdyt/items/1c92d70db3cfb03cc02c)
- https://github.com/ysdyt/ChristmasTree-Selfie



意味もなく連射撮影しないよう、直近60フレームのうち30フレームに顔が検出される（一定時間連続して顔が検出され続ける）とシャッターを切る条件になっています。
画像処理においては非力なRaspberrPiで高速に顔検出を行うために、顔検出を走査するウィンドウサイズを検知精度が落ちない程度に可能な限り小さくするなど微妙なチューニングも入っています。



## 2. 顔検知が行われたら音声ガイダンスを流して写真を自動撮影する

顔検知が行われたら、今回はwebカメラのシャッターではなく、RaspberryPiとWi-Fiで接続されたRICOH THETAのシャッターを切ります。
THETAのWi-Fi接続やAPIの使い方などは以下にまとめています。

- [Python3でRICOH THETA API v2.1を叩く](https://qiita.com/ysdyt/items/55771b1706308394fe78)



[前回](https://qiita.com/ysdyt/items/1c92d70db3cfb03cc02c)の反省点として、シャッターが切られる瞬間がユーザーからわかりにくいということがあったので、今回は顔検出の状態（バウンディングボックスの可視化）が見えるミニモニターを接続したのと、撮影のタイミングに音声ガイド（.mp3）を流し撮影カウントダウンを行うようにしました。カウントダウン音声は声優スクール所属の方に声を当ててもらったという謎のこだわりポイントもあります。笑

撮影したTHETAの360度画像はAPI経由でRaspberryPiのローカルに保存します。



## 3. 撮影した画像をDropbox APIで所定のフォルダに格納する

さて、ここからがめんどうなところです。

ローカルに保存した360度画像をLINE APIでLINEグループに投稿すれば完了なのですが、そうは簡単にいきません。

実は、LINE API経由で投稿した画像は**メタ情報が削除**され、360度画像ではなくなり、ただの2次元のパノラマ画像にされてしまいます（！）
※メタ情報が削除されないようにする方法はAPIの仕様として存在しないようです。

なので、どうしてもLINE APIを使わずに画像をLINEへ投稿する必要があります。

可能な限り手動オペレーションをなくしたかったのでいろいろ調べましたが、残念なことに**手動で**LINEに360度画像を投稿（つまり普通に画像を投稿するのと同じ）という手段しか無いようです。

それならばと、手動で操作するように見せかける自動化アプリなどないのか探したところ、スマホであればWorkflowというアプリで指定した手動処理をアプリが自動で行ってくれることができそうです。

- （参考）[「Workflow」で作業効率アップ！基本操作とオススメのレシピ5選](https://ferret-plus.com/7751)

RaspberryPiのローカルに保存された360度画像を（メタ情報を削除することなく）スマホに送ることができればWorkflowで半自動でLineに投稿することが可能のようでしたので、今回はDropboxを使って画像を以下のように転送して、最終的にスマホのローカルに保存する流れにしました。

RaspberryPiのローカル → Dropboxの指定のディレクトリ → スマホのローカル



上記の 「RaspberryPiのローカル → Dropboxの指定のディレクトリ」の移動はDropbox APIを使って画像を移動します。Dropbox APIをそのまま素直に使っています。

- https://github.com/ysdyt/Selfie-Theta/blob/master/dropbox_api.py



ちなみに、Dropboxに最新の画像が共有されたときにIFTTTでスマホにプッシュ通知を送ってもらおうとしたのですが、IFTTTにはそこまでリアルタイムな追従性はなかったため使えませんでした。画像が共有されてしばらく経った後や、最新+1枚目の画像が共有されたときにまとめて通知がくるという感じでした。



## 4.スマホアプリのWorkflowで半自動で画像をLINEへ投稿する

RaspberryPiのローカル → Dropboxの指定のディレクトリ → スマホのローカル

のうち、「Dropboxの指定のディレクトリ → スマホのローカル」の画像転送はWorkflowアプリを使って半自動で行います。



Workflowで行う内容は以下です。

1. 特定のDropboxディレクトリに転送された最新の画像を、スマホローカルの特定のアルバムに保存する
2. LINEが自動で立ち上がるので、投稿したい画像をローカルから選択 → 画像が投稿される。
3. 投稿された画像がスマホローカルから削除される。



これをレシピ化したものが以下です。スマホのWorkflowアプリで展開できます。

- https://workflow.is/workflows/2a973cfdfe4b4336b5ca8283a2220356

最終的には、このレシピを使って人間が画像をアップロードする操作を行います。LINE APIが360度画像をそのまま投稿さえくれればとっくに解決だったのに。



## まとめ

**「LINE APIでは360度画像が2次元パノラマ画像にされる」**という最大の障壁がありますが、Workflowなどを使うことで一部手動オペレーションが入ることを許容すれば、誰でもRICOH THETAを使って360度画像を撮影し、LINE上でみんなで共有する仕組みを比較的簡単に作ることができます。

今から思う改善点としては、ここでは顔検出をシャッターのトリガーとしていますが、Amazon Echoなどのスマートスピーカーをくっつけて、「アレクサ！写真撮って！」と言えばシャッターを切るようにした方が、精度的にもUI/UX的にも良いかもしれません。


## その他参考

- [raspberry pi上のpython3にpygameを入れる際のエラーを解決](https://qiita.com/hisurga/items/28651689eafe6ec89227)

- [ラズパイのオートスリープをOFFにする](https://blog.withachristianwife.com/2017/04/10/prevent-raspberrypi-from-sleeping/)