河本の実験室

河本が作ったものを紹介するブログです。こっち(https://kawalabo.blogspot.com/)から移転してきました。ポートフォリオ: http://俺.jp

「いま撮ってればよかった!」を無くす、さかのぼり屋内カメラを作った

子供と遊んでいると、予測不可能なタイミングで面白い事を言ったり、可愛い顔したり、初めて歩いたりします。そんなとき「カメラ回してればよかった!」と嘆いたことのある親は私だけではないはず。

f:id:kenkawakenkenke:20191106020510p:plain
そこで、事後にGoogle Homeに向かって「OK Google、いまの残しといて」と言うだけで過去に遡って動画を残しておけるカメラを作りました。

 

構成

f:id:kenkawakenkenke:20191106000323p:plain

素数が多く見えますが、一つ一つの要素は沢山の先人たちに踏み固められた技術です。今回の特徴はその繋ぎ方だけなので、要素の詳細説明は省きます。

動画の常時録画

まずUSBウェブカメラをラズパイにつなげて、常時録画し続けます。

  • ウェブカメラ: 僕はこういう制作には大体Logicool C920を使ってます。安くて画質いいので。
  • ラズパイ:僕が使ったのはRaspberry Pi 3Bですが、もっと新しいのあると思います。

常時録画といっても実は過去30秒だけを1秒ごとに区切って動画(TS)ファイルとして書き出し、古いファイルはどんどん捨てていってます。古いファイルを消していったほうがラズパイの容量が節約できるし、「ずっと撮られてる感」が減らせるので。

実際の録画には、ffmpegを使ってHLSで保存しています。ffmpegの設定は黒魔術感があって、正直あまり理解していません。沢山ググって色々な例を合成していった結果できたのが以下の呪文です:

ffmpeg \                   
-f alsa -thread_queue_size 1024 -i hw:1,0 \            
-f v4l2 -thread_queue_size 256 -s 640x480 -framerate 24 -i /dev/video0 \
-b:v 8000k -c:v h264_omx -bufsize 500k -r 30 -vsync cfr -g 24 \                                               
-c:a aac -b:a 256k -ar 44100 -bufsize 256k \
-flags +cgop+loop+global_header   -bsf:v h264_mp4toannexb \
-f hls -hls_list_size 120 -hls_time 1 -hls_flags delete_segments stream.m3u8

これをラズパイで走らせると、実行ディレクトリ内に「stream.m3u8」というインデックスファイルと「stream*.ts」という動画ファイル群が作られ続けます。

f:id:kenkawakenkenke:20191106003931p:plain

このtsファイル一つ一つが、撮られた1秒毎の動画ファイルです。

Google Homeから呼び出す

Google Homeから発声を受け取って、ラズパイで任意のコードを実行させる方法は、沢山ネットに載っています。「ラズパイ google home」とかでググりましょう。

僕は「OK Google、リビングの動画を残して」というと、ラズパイで実行しているPythonプログラムが通知を受け取れるようにしました。

動画を結合する

Google Homeから通知を受け取ったら、ffmpegを使って出力用の動画ファイルを作ります。

RUN_ID=`date +%Y%m%d_%H%M%S`
OUTPUT=/tmp/output_$RUN_ID.mov
MYLIST=/tmp/$RUN_ID.txt

echo "" > $MYLIST 
for file in `ls -v /var/www/html/livecam/stream*.ts|tail -n $((DURATION+1))|head -n $DURATION`;do                                        
 echo "file $file" >> $MYLIST                  
done                       

ffmpeg -safe 0 -f concat -i /tmp/mylist.txt -acodec copy -vcodec copy -y -f mov $OUTPUT

まず、録画したtsファイルを新しい順に並べ、最新の30個(=30秒ぶん)のファイル名を書き出したテキストファイルを作ります。

f:id:kenkawakenkenke:20191106011128p:plain

これをffmpegに投げて、結合しつつひとまとめのmovファイルに書き出します。これで、過去30秒を映した動画ファイルができました。

ちなみにmp4に書き出したら何故かGoogle Photosへのアップがうまくいかなかったので、movを使っています。

Google Photosにアップする

Google Photosへのアップにはrcloneを使います。rcloneとは色々なクラウドサービスのファイル操作を担ってくれる便利なツールです。

公式ページがとても親切に書かれているので、設定に迷うことはないと思います。

rclone copy $OUTPUT gphoto:upload -P

先程作った動画ファイルをアップしましょう。(gphotoのところに自分が設定したGoogle Photoのターゲット名を入れる)

やってみた

こんなふうにクロマグロのぬいぐるみで遊んでいるときに、ふと今までの出来事を撮っておきたいと思ったとしましょう。「OK Google、リビングの動画残して」とつぶやきます。

www.youtube.com

一分後ほど待つと、遊んでいるときの動画がGoogle Photosにアップされます。

f:id:kenkawakenkenke:20191106014030p:plain

こんな動画が撮られます:

www.youtube.com

さいごに・・・

  • カメラを持ち歩かずに言葉だけで「撮れる」のは本当に便利です。特に、「撮りたい瞬間にカメラを構えていなくても大丈夫」という安心感のおかげで、子供との遊びに集中できるのが嬉しいです。
  • ただし、たまに音声入力がミスって「申し訳ございません、お役に立てそうにありません」とか言われてしまいます。過去30秒しか撮れないので、これは焦ります。「OK Google、いまのを『長めに』残しといて』と言えば5分ぐらい録画を残すようにすればいいと思います。
  • 僕はカメラの未来は「ずっと録画してAIが良いシーンを選別」だと信じてますが、それができるまでの間はこういうハックでQOLをあげていきましょう。
  • 関係ないですが、上の子が初めて立つ瞬間はたまたまカメラを回していたおかげで撮れました。月イチぐらいでリピート再生する宝物です。こういうツールを使って、もっと宝物が増えたら嬉しいですね。

つまらない安全講習ビデオをディープフェイクで「自分ごと化」する

安全講習のビデオってつまらないですよね。

免許の更新、社内のeラーニング、飛行機の離陸時など、様々な場面で僕らは講習ビデオを見させられます。

いくら役者さんが迫真の演技で危険な場面を演じても、僕みたいに共感力が薄い人間にはどうしても「他人事」に見えてしまって適当に見流してしまいます。本当は大事なのに。

そこで、安全講習ビデオを無理やり「自分ごと化」する方法を考えて試してみました。

事故ってるのが自分と家族だったら流石に見るんじゃない?

役者が演じる事故映像は「もしこれが自分や家族だったら」という変換を一旦行わないと吸収できません。しかし、自分や家族が危険な目にあっている場面を見れば直接脳の「ヤバい」エリアに働きかけられるのではないかと想像します。

そこでディープフェイクを使って、事故る対象者を自分や大事な人に変えてしまえば、急に「自分ごと」として捉えられるんじゃないかと考えました。:

f:id:kenkawakenkenke:20191011004106p:plain

ディープフェイクとは、機械学習を使って映像内の人を別の人に置き換えてしまう技術です。世間ではフェイクニュースやリベンジポルノで悪名高いやつですね。上の画像では、運転者の顔を僕の顔に置き換えています。

映像で見ると、かなり綺麗に(メガネも含めて)置き換えできていることがわかると思います。(ちなみに同乗者全員僕に置き換わってます。):

 

 

元映像: (警視庁公式チャンネル) 交通事故防止 「命を守るシートベルト」 後部座席着用

元の映像では「知らん人が危ない目にあってる」ぐらいにしか見えなかったシチュエーションが、自分が置き換わることで少しだけドキドキ感が増した実感があります。(僕を知らない人からすると、知らん人が知らん人に置き換わっただけなので全く分からないかも知れませんが。) 

このような、自分や大事な人を出演させた「自分ごと化」映像を新米ドライバーや交通違反者にプレゼントしたら、少し危険の実感が増して、安全運転が望めるのではないでしょうか?

とはいいつつ、あまりに髪型が違うことや、同乗者が知らない人たちであることで、まだ少し違和感が残ります。同乗者をそれぞれ自分の家族に植え替えていけば、かなり現実感が増すんじゃないかと想像しています。あまり子供の年代が合っている映像が見つからなかったので試せませんでした。

 

他にも自転車事故を起こす河本の映像を作ってみたり:

元映像:(JA共済DVD)「危険を予測してみよう! ~被害事故~」

骨格が違いすぎて、あまり当てはまってない気がします。

 

下水機能が停止したトイレを流して怒られる河本:

 元映像:(国土交通省公式チャンネル)災害時のトイレ、どうする?

 

調子に乗って極秘情報をネットで漏らす河本:

 元映像:(警視庁公式チャンネル)みんなで学ぼう!サイバーセキュリティ ①情報流出防止対策

これはちょっと似てますね。やはりもとの毛髪量が似てるほうが良さそうです。

やりかた

"faceswap"という、顔の抽出、学習、合成、映像の書き出しまで全部やってくれるツールを使いました。ほぼ、工夫の要素はなく、使うだけです:

GitHub - deepfakes/faceswap: Deepfakes Software For All

おわりに

映像を知っている人にすることで「他人事」を「自分ごと」にするという考え方は、色々応用がききそうです。例えば少し違う角度では、歴史写真に適用すると興味深い効果があるのではないかと思います。

教科書やドキュメンタリーなどで見すぎて実感が湧きにくくなった歴史的な写真や映像に自分や家族を出演させることで、「そこにいたのも自分と同じような人間なんだ」という実感を増す効果があるんじゃないかと想像します。モノクロ歴史写真をカラー化すると急に親近感と現実感が増すのと同じだと思います。なんとなく色々面倒くさそうなので、アップするのは自重しますが。

ディープフェイクは悪名が轟いていますが、視点を変えるとこのように(少しだけ)人のため世のためとなるような使い方がまだまだ転がっている気がします。faceswapは驚くほど簡単に使えたので、是非新しい使い方を考えて試してみてください。

「見せたい人にしか見えない注意書き」を色々作ってみた

見せたい対象者以外には見えない注意書きを一人ブレストして5つほど試作してみた、という話です。

なんで?

注意書きが駅や公園や道路などの公共空間に溢れかえっているのが最近気になっています。特に、多くの注意書きは自分には関係ない or 既に知っている事であるため、本当に見ないといけない内容が埋もれてしまっています。

Web広告の分野では、興味のないバナー広告を見すぎるとBanner Blindness*1 が発生することが知られていますが、同じように注意書きも意識から排除してしまっている自分に気づくときがあります。

ならば、注意書きもWeb広告と同じように個々の利用者にとっての関連性を向上させることで、(1)伝えるべき注意がもっと伝わるようにしつつ、(2)注意書きの総量を減らして空間の外観を守ることができるのではないしょうか?つまり、見ないといけない人しか見えない注意書きを作ることが出来ればいいのでは?

そんなことをボーッと考えていたら色々なアイディアが浮かんだので、簡単に試作してみたものを紹介していきます。実現性の薄いものも含まれますが、考えるきっかけになれば幸いです。

その1:フラッシュを焚くと怒る展示台

美術館、観劇など、フラッシュ撮影が禁止されている場所は沢山あります。展示物や体験への悪影響を考えての切実な注意書きですが、個人的には美しい展示室内に「フラッシュ禁止」マークがいたるところに掲示されることによる外観への影響が気になることがあります。そこで、せめて知ってか知らずかフラッシュを焚いてしまった人を叱り、二回目以降を妨げる方法としてこんなのを作ってみました:

 黒い再帰反射シートの上に文字を切り出した黒いマスクを敷くと、文字が見えなくなります。(ぴったり合わせて塩ビシートをかぶせると、ほぼ見えなくなります。)

f:id:kenkawakenkenke:20190804025041j:plain

それをフラッシュ撮影すると、文字(「NO FLASH💩」)だけが光って見えるという仕組みです。

f:id:kenkawakenkenke:20190804025057j:plain

こうすれば、ルールを守っている人からは黒い台にしか見えない一方、ルールを破ってしまうと明確に怒られ、しかもインスタ映えしない写真に変えてしまえます。

f:id:kenkawakenkenke:20190804043707p:plain

また再帰反射材を使っているおかげで、他の人にとっては体験が壊れることなく「ただの黒い台」に見え続けます。


もちろんTwitterコメントで指摘されているように、一度目のフラッシュを止めることも大事です。しかし美術館の入り口で「フラッシュ撮影は禁止です」と伝えた上で、それでも撮影してくるような困ったさんは、おそらく既存の「フラッシュ禁止」サインでは防げません。このように「ルールを守っている人の体験は壊さず、」「ルールを破ったら思いきり怒る」注意書きのほうが、結果的に効果が出ると思うのでしょうがどうでしょう?

その2:ヘッドライト無点灯だと怒る看板

再帰反射材を逆に使って、「ライトをつけていないと叱る看板」を作ってみました。通常の「ヘッドライトつけろ!」看板は(他の注意書きとの兼ね合いから)トンネルに沢山つけることはできませんが、これならば無点灯の人だけにターゲティングして叱れるため、トンネル中にびっしり設置しても構わないわけです。

黒い再帰反射材の上に白い切り抜きマスクで文字を書くと、ヘッドライトをつけている人からは文字が白飛びして読めず、無点灯の人からは黒い文字が見える仕組みです。

なんかトンネル以外にも色々応用効きそうな構造ですね。

その3:撮ろうとすると怒るTシャツ

イベントとかで「今日は写真撮られるとまずいなー」っていう日、ありますよね。実はiOS/Androidの標準カメラはデフォルトでQRコードを読み取り、内容を画面上に表示させる機能があります。その機能をハックして、自分を撮影しようとしている人の画面上に任意のメッセージ(例えば「写真やめてね😘」)を表示させることを思いつきました:

肉眼で見るとなんの変哲もないQRコードTシャツですが、スマホカメラで撮影しようとするとこんなふうに画面上に注意書きがポップアップします:

f:id:kenkawakenkenke:20190804040618p:plain

写真は撮る前に声をかけるのが礼儀ですが、これならば勝手に撮ろうとしてくる不届き者にだけ、少し強めに叱ることができます。スマホカメラ以外には無力ですが。

せっかくなのでこちらでオーダーできるようにしときました:

clubt.jp

撮影者にだけメッセージを送れるのは、他にも色々応用が効きそうですね。例えばSNOWでかけてほしい修正パラメーターを指示したりとか。

その4:搭乗時間が近づくとパニクる搭乗券

未だに紙の切符は飛行機や地方の電車等で健在です。久しぶりに紙の切符を手にすると、出発時刻とスマホの現在時刻を見比べたりするのが意外とストレスになったりします。そこでこんなのをつくってみました:

時間が経つと消えるインク」を使って搭乗時間に近づくと「ヤバイヨ」メッセージを表示させる切符です。

f:id:kenkawakenkenke:20190804041352p:plain

実際は消え方が温度など色々な外部要因に依存するため今の所あまりぴったり制御できていません。なので搭乗券のような重要な用途での実現は少し難しいかもしれません。

一方、「客に渡す物に少し経つとメッセージが現れる」という方式は色々応用効くんじゃないかと思います。持ち帰りの食品を食べ終わったころぐらいにパッケージングに「ちゃんと分類して捨ててね!」と表示したり。

その5:逆走しようとすると怒る通路

人の動線が複雑な駅って、矢印だらけですよね。自分の行き先とは関係のない矢印を全て視界から消せたら、どんなにすっきりするでしょうか。それを実現しようとしたのがこれです:

 紙をシャッター上に分割し、一つの方向から見ると緑色の矢印、反対方向から見ると赤色の「✕」が見えるようにしました。こうすることで、R2D2ダースベーダーも(自分から見て)右を歩けばいいことが明らかなので、ぶつからずにすみます。

レンズアレイを使えば2方向だけじゃなく多方向にも対応できますね。

通常の指示表示では、他の注意書きとの兼ね合いからせいぜい「矢印」や「右側通行などの文字」を表示することしかできません。しかしこの方式ならば、視覚的に「床全部を赤くする」といった思い切ったことができるため、非常に混み合った駅でもすぐに歩くべき場所がわかるという良さがあります。

他にも・・・

  • タバコの煙を吐くと、プロジェクターの映像が煙のなかに結像して目の前に広告が出るとか
  • 一定速度を超える(か下回る)と可聴域に入る不快音を作って、スピード違反をへらすとか
  • 歩道を自転車で走っている人にしか見えない看板とか

色々作れたら面白いんじゃないかなぁと考えてます。

さいごに

それぞれ実社会に実装するには更にひとふた工夫必要なアイディアを、色々試作してみました。個人的に、電子工作・プログラミングでも(なんならもっとちゃんと)解決できる問題を敢えて「アナログな物の構造」だけで解決することに不思議な楽しさを感じました。

*1:広告っぽいものを全て意識から排除して「見えなく」なってしまう現象

「ポケットに入れたままメールを読む」を実現する『モールス通知』を作った

こんなアプリを作りました:モールス通知

いろんなアプリの通知を文字や音ではなく「振動」で伝えるAndroidアプリです。モールス信号が分かる人なら、訓練すればポケットに入れたままメールが読めるようになるはず。

動画を見ると雰囲気が分かると思います:


なんで?

最近歩きながら大事なメールを待ち構えることがあり、スマホが振動するたびに立ち止まって画面を見ている自分に気づきました。「ポケットからいちいち出さなくても要件がわかればいいのに!」と思って作ってみました。

イヤホンで聞けばいいじゃんとか言われがちですが、僕は「歩きイヤホン」反対派です。むかし後ろから近づいてくる不良に気づかなかったことがあるので。気をつけよう。

仕組み

Play Storeでアプリを公開しつつも、今回はソースをGithubにアップしました。何故かというと少し危ない「通知へのアクセス」許可をユーザーから頂くからです。自分だったらソースも公開されていない個人アプリに通知閲覧を全て許可するのは怖すぎるので、せめてソースを読めるようにしておきました。

せっかくなので、以降はソースを参照しながら作り方を解説していきます。

通知を受け取る仕組み

本アプリは、他のアプリが受け取った通知を全部読み取れる必要があります。これは「NotificationListenerService」といって、危険でパワフルな権限です。通知が読めるというのは、メールや電話番号が(通知バーに表示されている部分は)すべて読めるということです。信用してないアプリには絶対許可しちゃだめです。

AndroidManifest.xmlにintent serviceを追加するだけでは足りなくて、

<service android:name=".NotificationIntercepterService" android:label="@string/app_name" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
  <intent-filter>
    <action android:name="android.service.notification.NotificationListenerService" />
  </intent-filter>
</service>

Androidの設定の「通知へのアクセス」画面でユーザーに明示的にアプリへの許可を与えてもらう必要があります。

そうすると、スマホに来るすべての通知が受け取れるようになります:

    override fun onNotificationPosted(sbn: StatusBarNotification) {
        val packageName = sbn.packageName
        val text = sbn.notification.tickerText ?: return
        // textに「Kenさんがリツイートしました」みたいな文字列が入ってる。
        ...
    }

ちなみにStatusBarNotificationからどの程度情報が取れるかはアプリによってまちまちでした:

  • TwitterだとDMの送信者や内容
  • Lineもメッセージの送信者や内容
  • Gmailアプリは送信者の名前だけ

想定していた用途では送信者の名前さえわかればいい気もするので、だいたい十分です。

執筆時点でのアプリはTwitterだけ少し特別な変換を行って、リツイートは「rt」とだけ再生してます。他に特別な表示の仕方をしてほしいアプリがあったら要望教えてくれたら作るかもしれません

和文をモールス信号に変換する仕組み

さて、Lineに「お腹空いた。帰り何時?」みたいなメッセージが来たら自分のアプリで受け取れるようになりました。英文ならばこれをそのまま欧文モールス符号に変換するだけです。
一方、和文モールス符号漢字をそのままモールス符号に変えることはできないため、もうひと工夫必要です。
今回はAndroidから使いやすい形態素解析ライブライのKuromojiのお世話になりました。
形態素解析とは文章を見て単語(正確には形態素)に分けつつ、読みや品詞を判別する作業です。
Kuromojiの出力のToken#pronunciation()を使って、

原文 : お腹空いた。帰り何時?
変換後:オナカスイタ。カエリナンジ?

というように読みに変換し、和文符号に割り当てます。

モールス符号に合わせてスマホを振動させる仕組み

ただモールス符号列を振動長に変換してandroid.os.Vibratorに渡すだけです。
つまづく点としては、配列で渡す最初の値は待ち時間だということです。気をつけましょう。

まとめ

ぼく実を言うとモールス信号全然わかんないんですが、このアプリを一日使っているだけで「・ー・ ー」(RT; リツイート)が分かるようになりました。
多分どんなに訓練しても正確に通知内容を読み取るのは難しいと思うのですが、「何言ってるのかわかんないけど何となくあの人からのメールな気がする」という直感を育てるのは出来そうだと感じました。
正確な情報伝達をせずに「なんとなく」で伝えるアンビエントな情報伝達手段、意外といろんな場面で使えるんじゃないですかね。
画面を見ずに「いま日経平均が2万円割れた気がする」とか言えるの、中二病心をくすぐられません?

「これ部屋に置いたらどんな感じ?」を秒速で可視化する「ARで見る」を作った

前回に続きまたARアプリを作りました:ARで見る

文字で書かれた数量(大きさ、体積など)を一瞬でARで可視化する便利アプリです。先週作ったアプリなので僕のTwitterを見てる人は今更感あるかもしれないですが、作るにあたって考えたこととかを少し整理させてください。

f:id:kenkawakenkenke:20190120223430p:plain

使い方はビデオを見てもらうのが一番早いと思います:

ブラウザ(など)で寸法を選択し、「共有」から「ARで見る」を選択すれば、すぐにARで可視化されます。 例えば買う予定の装置の置き場所を考えたりするのにとても便利です。

なんでこんなの作ったの?

友人と装置の話をしていて、寸法を見ながら「こんぐらいかな?」と手を広げているのを見て「昭和だな〜」と思ったのがきっかけでした。世の中にはARを使った巻き尺アプリは死ぬほどあるのにも関わらず僕が使おうしなかったのは、既存アプリのUXが(僕の)日常と乖離しているからだと考えました。寸法を覚えて、アプリを開いて、数字を入力して、床をタップして、ようやくARで表示とか絶対やりたくないじゃないですか。

「ウェブページで寸法を見ている状態から最短でARまで持ってくる」ところを突き詰めたアプリがあれば、ちゃんと日常で使えるものになるんじゃないかと思い、「テキスト選択→共有」で開けるARアプリを開発しました。

何に使うの?

上記例の「大きさ」(高さ・幅・長さ)は家具や装置を部屋に置いた時のイメージを掴むのに使ったり:

f:id:kenkawakenkenke:20190120230117p:plain

洗濯機がドアを通るか試したり:

f:id:kenkawakenkenke:20190120230238p:plain

なにかと便利です。

表記方法はかなり広く対応しています。アプリが理解できないテキストを見つけたら是非河本にご一報を。

 

また、大きさに限らずあらゆる「これどれぐらいだろう?」を答えることを目指しています。例えば速度:

 ナマケモノの最高速度が秒速3cmと言われてもイメージしにくいですが、実際にボールが動いているのを見ると素直に「おせぇ!」と実感できます。

「4km/h」「時速5キロ」「12ノット」「マッハ2.4」などの表記に対応しています。

 

体積:

ペットボトルでイメージしやすい少量の体積には使う必要性が薄いかもしれないですが、「四千立方メートルのプールの水を無駄にした」みたいなニュースを実感するのには非常に便利だと感じています。

 「4.6L」「50cc」「2合」などの体積の表記が理解できます。

 

さらに、基本的な物理量以外にも拡張できます。例えば「金額」:

日本円の表記を入力すれば、 1万円札の束で置いたらどう見えるかすぐに可視化できます。これで部屋に5000兆円を置く遊びとかもできるわけです。現金強奪事件とかの被害額を札束として見てみると「これ持って逃げるの大変だったろうな」といった新しい感想が芽生えます。

こだわったところ

このアプリの肝は

  1. 他のアプリで寸法を見て『これどんぐらいだろ』と考えてから最短でAR表示すること
  2. あらゆるアプリから汎用的に使えること

の2つです。そのために(プロダクト)デザイン的にこだわった箇所をあげていきます:

  • 「テキストを選択して共有」に特化する。

ブラウザやOSの基本機能として搭載されない限りは、寸法を汎用的にARに持っていくための最短ルートは選択→共有です(多分)。そのため、アプリの機能をすべてこのエントリーポイントに特化させ、他の入力方法は敢えてサポートしないことにしました。

「選択→共有エントリーポイントをメインに持ちつつ、普通にホーム画面からアプリを開いて数字を入力させるパスも用意しときゃいいじゃん」というコメントも分かるんですが、そうすると必ず欲が出てメインのエントリーポイントがおろそかになると思ってます。チームで開発して強いPMがついていればいざしらず、僕一人では弱いのでこういう縛りを設けました。暇になったらそっちも考えるかもしれないですが。ていうかそのパスは他の巻き尺アプリで十分だよね。

  • 修正要らず。

『これどんぐらいだろ』からARで開くまでの間に数字を入力させたり微調整が必要だったりしたら最悪のUXです。そのためそもそも修正手段を無くし、実装としてはなるべく沢山の寸法表記のパターンを一発で理解できるように強いテキストパーサーを作りました。このために国内外のECサイトを巡って寸法表記をかき集めて実装しました。

大きさの寸法は、

次元の記法がバラバラだったり:「高さx幅=20x40」 vs「高さ20 幅40」

単位の記法がバラバラだったり:「高さ(mm) x 幅(mm)=20x40」vs「20mmx40mm」

結構ややこしいんです。

  • すぐAR

最短でAR表示できるように、シーン内のモデルの挙動にこだわりました。

一般的なARアプリはだいたい「起動してから床を認識するのを待って、床をタップしてようやくモデルが出現」みたいな流れに則りますが、これではあまりに遅すぎると考えました。そこで、アプリが開いてから環境を認識するのを待たずにすぐモデルをカメラ前に浮かばせて、床が認識できた時点で「ドサッ」と落ちてくるような挙動にしました。これにより、寸法を「共有」してから1~2秒程度でモデルが見れます。

次のステップ

  • テキストを選択→共有の基本UXを崩さずにもっと色んな日常的なニーズに応えられる方法を考えています。例えば大きさのmin-maxが表記されていた場合だけはスライダーを出してサイズ調整できるようにするとか。ページの他の情報からテキスチャを貼るとか。履歴を残して複数オブジェクトを置いていけるようにするとか。
  • とは言いつつ、情報の修正が必要な場合があることもわかってるので(特に高さ/幅/長さの入れ替え)、このアプリに馴染む修正方法を考えてます。
  • あらゆる「これどんぐらいだろう?」に応えられるように、表現出来る量を増やしていきたいです。例えば「5万人の群衆」に囲まれるのってどんな感じだろうとか。400luxってどれぐらいの光だっけ、とか。知らない言葉を辞書で引くのと同じように、イメージできない数量を「ARで見る」のが当たり前になるように普及させてみたいです。

さいごに

お昼食べながらふと考えたアプリが思いがけなくバズって驚きました。想像ですが「家具の寸法を数字で入力したらARで表示できるよ」というアプリだったらここまで話題にならなかったと思います。このアプリの新規性と魅力はARではなく、「選択→共有するだけで部屋の中で見れる」という体験です。実際に使う状況を思い浮かべて、間のあらゆる障壁を取り除いたUXを作るの、めっちゃ大事。

付録:対応している表記の例

大きさ

  •  寸法(幅W×高さH×奥行D)(mm) 95×150×235
  • 幅640×奥行600×高さ1039mm
  • 70mm×124mm×364mm (←軸の指定のない場合 幅x高さx奥行きとして解釈)
  • 70x124x364(←単位の指定のない場合mmとして解釈)
  • 高さ123m
  • 半径42.5mm(←円として表示)
  • 直径10cm

容積

  • 1m^3
  • 4000立方メートル
  • 123L
  • 1カップ

速度

  • 時速72キロメートル
  • 72km/h
  • 5ノット
  • マッハ3

金額

  • ¥4800万
  • 3000兆円
  • 24 million dollars

自然現象

  • 風速12m

見えない空間データを可視化する「AR Sensor」を作った

(今回から河本の実験室の記事は、こっちに書くことにしました。そのうち過去記事も移転します。)

"AR Sensor"というアプリを作りました。

f:id:kenkawakenkenke:20190105222927p:plain

データをARで投影することで、普通は見えない日常の中の様々な空間データを見えるようにするツールです。

例えばこんなふうに、Wifiルーターから出てくる電波の立体的な強弱を見ることができます(緑は電波が強いところ、赤は電波が弱いところ):

f:id:kenkawakenkenke:20190105181636g:plain

AR Sensorで見るWifiルーターの上の電波強度

なんでこんなの作ったの?

もともとは「週一ぐらいでどこからともなく流れてくる排水口の臭いのもとを突き止めたい」という家庭的な悩みを解決するためにこのツールを作りました。臭いの空間分布を可視化できれば、臭いの元がすぐに見つけられるんじゃないかと。

使っているうちにWifiや磁場などのスマホで測れる様々なデータに応用すると便利+教育的であることに気づいて、汎用的なアプリとしてリリースしました。

なにが測れるの?

バージョン1.0で表示可能なのは「Wifi電波強度」「Bluetooth LE電波強度」「磁場」「気圧」「LTE(携帯)電波強度」の5種類です。それぞれの面白さを紹介していきます。

Wifi電波強度

スマホが繋がっているWifiルーターの電波強度を測定し、空間にプロットしていきます。

f:id:kenkawakenkenke:20190105194138g:plain

AR SensorでみるWifiの電波強度分布

例えば我が家では2階にルーターが置いてあるため、階段の中程でようやく良い信号(緑)になることが見えます。ルーター配置を最適化したり、ホテルのロビーでWifiが捕まる場所を探すのに使いましょう。

Twitterで少し勘違いしている人がいたので明確にしておくと、AR Sensorは「スマホが通った場所のセンサデータを随時記録して表示するツール」なので、上の動画を見るとわかるように通った場所のWifi電波強度しかわかりません。部屋全体を「見」たければ、部屋全体にスマホを動かす必要があります。頑張ってください。

余談ですが、アプリの現バージョンでは測定した点が「いい感じに」緑から赤が分布するように勝手に調整しています。このモードをOFFにしたい場合は設定画面から「色を動的に更新」をOFFにして、手動で最小値(赤)〜最大値(緑)を設定しましょう。

f:id:kenkawakenkenke:20190105194609p:plain

 Bluetooth LE電波強度

Wifiと同じように、Bluetooth LEの電波強度(RSSI)を可視化します。

f:id:kenkawakenkenke:20190105205137p:plain

例えばこれは中心のスマホBluetooth電波強度を測定した結果です。真ん中にアルミホイルの壁を設けてあるせいで、右側は左に比べて電波強度がガクっと下がる(赤くなる)のが見えますね。このように、「シミュレーションでは見たことあるけど実際どうなんだろう」が可視化できるのがこのツールの面白さです。

磁場

スマホには磁気センサー(ようはコンパス)が入っています。地図アプリなどで方角を示すのに使われています。これをAR Sensorで可視化すると:

f:id:kenkawakenkenke:20190105211218g:plain

AR Sensorでみる地磁気

このように、北極に向かって粒子が流れていきます。(地面に向かっているのは、東京では伏角が49°、つまり地面の先に北極があるからです。)

また磁石の周りの磁場も見てみましょう:

f:id:kenkawakenkenke:20190105211904p:plain

頑張れば教科書で見たことのあるような磁力線が立体的に見ることができます。

2つの磁石を並べると、一つの磁石からもう一つの磁石に向かって磁力線が繋がっているのが見えますね。

f:id:kenkawakenkenke:20190105212157g:plain

AR Coreでみる2つの磁石の周りの磁力線

これまでは砂鉄とかを使って二次元的にしか見れなかった磁場を、スマホだけで三次元的に見ることができるようになりました。

気圧センサ

あんま面白くないので割愛します。

LTE電波強度

加筆 (2019/1/6)

携帯の電波強度です。携帯の繋がりにくい居酒屋でベストな席を探すのにご利用ください。

f:id:kenkawakenkenke:20190106124100g:plain

ガスセンサ+Arduino+シリアル通信

AndroidArduinoを繋げるのが物凄く簡単だって知ってましたか?こういうホストケーブルで繋げば普通にSerial通信でデータのやり取りができます。

例えばこんなふうにガスセンサをAR Sensorとくっつければ、お湯を沸かしている時のガス分布を見ることができます。

f:id:kenkawakenkenke:20190105223758j:plain  f:id:kenkawakenkenke:20190105224005p:plain

これを使えば、スマホに搭載されているセンサ以外にもなんでも組み合わせられるということです。何か測ったら面白いもののアイディアがあったら是非教えてください。

ちなみに今回は面倒だったのでAR Sensorのリリース版にはシリアル通信機能は含めていません。そのうち作ります。

実装の話

今回初めてARCoreとSceneformを使ってアプリを作ってリリースしました。これからAR開発をしてみようと思っている人向けに、開発の流れをメモしておきます。

なんでSceneform?

Sceneformは面倒なOpenGLに触れなくても3DアプリがかけるJavaの3Dフレームワークです。僕はUnityのような現代的な開発環境がよく分からない古いエンジニアなので、Javaだけでゴリゴリ開発できるSceneformが好適でした。

学ぶ

Sceneformが提供するサンプルプロジェクトがとても簡単なので、特に迷わないと思います。

hellosceneformで基本的なセットアップに必要なもの(ArFragment, AnchorNodeなど)の取扱いを学びましょう。

solarsystemで変形やアニメーションを学びましょう。完全に余談ですが、天王星の向きがおかしいバグを見つけたのでPRを出してみました。練習に使うなら気が狂わないようにこっちの修正版を使いましょう。

次のステップ

次にこんな機能作ります。Twitterで「これがほしい!」といってくれれば作るかもです。

・ シリアル通信のデータを読み込む機能をリリース版にもいれる

・Cloud Anchorでデータの共有ができるようにする。例えば教室で先生が磁石の周りでグリグリしているのを生徒たちが自分のデバイスで見れたら素敵じゃない?

 さいごに

「位置情報とセンサデータを3Dで取得して表示するツール」というのは10年ぐらい前からずっと作りたかったものなんですが、今までは位置情報の取得が面倒で躊躇っていました。「環境に設置した複数のカメラで位置を測る」とか「QRコードを部屋中に貼る」とか「Kinectで右手の位置を測る」とか、やればできるけど実装+環境構築コストが少し大きい手段しかなかったからです。AR Core(に搭載されたSLAM)が優秀なおかげで面倒な位置情報処理のコードを一行も書かずにシステム構築でき、センシングから位置取得から表示までスマホ一台で完結できたことが一番の驚きでした。是非皆さん(特に今回Pixelを買った人)には手元のスマホの力を感じてもらいたいです。

Get it on Google Play

追記1 (2019/1/6):用語がよくわからなかったので「磁力」と書いてました。正しくは「磁場」ですね。直しました。