2016/11/12

【アプリ紹介】馬場タクシー3D: 人手が足りません! / BabaTaxi3D


今日は 2013/10/7 に公開した「馬場タクシー3D」の紹介です。




こんなアプリ

東京を舞台にお客さんを乗せて目的地まで爆走する、東京エリアとしては世界初のタクシードライビングシミュレーターです。

結構本格的な 3D ゲーです。(個人の感想です。)



ゲーム実況する方も出現。





開発の経緯とこれから

リアル東京を走れるドライビングシミュレータがやりたくなったので作りました。

今後も引き続き、もっとリアルに、もっと面白くしていく予定です。
定期的なチーム戦の充実化、Android 対応とかも。

開発期間

大学生のころプロトタイプを DirectX で作り始めてそのうち飽きて放置していましたが、iPhone が普及しだして「あぁこれはスマホで作るべきだ」とまた作り始めて、途中飽きて放置してまた作り始めてを繰り返して今も改良を続けているので期間としては結構な年数やっていて、なんというかもはやライフワークみたいになっています。

人生何もしないには長いですが、巨大資本や人手が大量に必要なものはいまいち自分でコントロールした感がなく、そういう意味では自分にとって退屈しない手頃なサイズのプロジェクトだなぁと思っています。

技術的な解説

簡単に言うと、ODbL に基づいて無料で商用利用できる地図 OpenStreetMap のデータから動的に 3D ポリゴンを作って、Bullet で物理演算して OpenGL ES で描画しています。

車やキャラクター、木などのモデルは Blender で作りました。

山手線上半分にある建物をすべて収録してアプリ配布サイズを 100MB に収めるためにいろいろな部分にて独自技術を編み出して使っています。

その他ノウハウとかアルゴリズムとか 1 記事にはとても入らないほどあるのでここでは省略。

一部は以前書いた 馬場タクシー3Dと競技プログラミング にて紹介しています。


以上、「馬場タクシー3D」の紹介でした。




2016/11/11

【アプリ紹介】分身カメラ / CloneVideo


今日は 2012/11/18 に公開した「分身カメラ」の紹介です。




こんなアプリ

動画の中の動いている人や物を分身させる、不思議な動画作成アプリです。











みなさん面白い動画を作っているようで。


開発の経緯とこれから

あまりよく覚えていませんが、前景と背景が分離できればこんな分身動画が作れそうだなと思ったのがきっかけだった気がします。

今後としては、リアルタイム生成あたりができたらもっといいかなと思います。
作った当時は iPhone5 が最新でしたが、今はその頃と比べると性能もかなり良くなっているはずなので。

今後もこういう「おやっ?」と思うようなひとクセあるアプリを作っていきたいところです。(感じ方には個人差があります。)

開発期間

開発日誌を書いてなかったころのやつなので不明ですが、ソースコードのタイムスタンプからすると 2012/10/13 あたりから作っていたような記録があります。レビュー待ちを 1 週間として、3 週間くらい?

技術的な解説

入力動画の最初のフレームを「背景」として、「背景」を作業のための N フレームにコピーします。

次のフレームからは背景と差があるピクセル付近を「物体」とみなし、フレーム i の「物体」を i % N 番目の作業フレームに合成します。
「物体」の検出については、単純な画素の差だけだと結構ノイズが出てしまうので、いろいろごにょごにょしています。

入力をすべて処理し終わったら、作業フレームと BGM を AVAssetWriter を使ってファイルに書き出します。

改めて振り返ってみると、かなりシンプルなアルゴリズムですね。


以上、「分身カメラ」の紹介でした。










2016/11/10

【アプリ紹介】97days


今日は 2014/4/25 に公開した「97days」の紹介です。



こんなアプリ

スマホに入っているたくさんの写真や動画を自動的にまとめて音楽付きのハイライト動画を作るアプリです。

「あなたの 2016 年を 15 秒の動画にまとめる」
「あなたの歴代クリスマスを 30 秒の動画にまとめる」
「あなたの最近 1 ヶ月を 5 秒の動画にまとめる」

といったことができちゃいます。

撮影場所を大まかにまとめた地名や、撮影時刻に近い自分のツイートも字幕として映像に合成することができます。

なので「そのとき何をしていたか」が分かって懐かしい気分に浸ることができます。

開発の経緯とこれから

スマホで写真をたくさん撮るけど、昔のやつってめったに見返さないよなぁ、なんか面白いことできないかな〜と考えてて、
ハイライト動画を作ったら過去を思い出しておもしろいかも、と思いついたのがきっかけです。

今 (iOS 10, 2016/9/13 以降) では iOS 標準アプリにも似たような自動生成機能が搭載されるようになってしまいましたが、これを作った当時はなかったので自分なりに欲しい感じのものを作ってみました。

この手のはどうせデバイス側の容量不足で写真をどこかに移さざるを得ないので、スマホでやると比較的最近のハイライトしか出せないなぁ、バックアップ先の PC なりクラウド側でやらないとつらいよなぁと思いつつ作っていましたが、その後 Google Photos のアシスタント機能で写真バックアップからまとめ動画自動生成や昔の写真紹介ができるようになって、あーもうこれでいいや、充分便利だ、となりました。

  〜完〜

悔しいのでちょっとあがくと、撮影日時付近のツイートを動画に合成する機能は上記 2 サービスにはまだ入ってないようです。
写真や動画に限らず、「そのとき何をしていたか」が分かる情報って後から見返すと結構楽しかったりするので、そのうち似たような機能が追加される、かもしれません。

あと、スマホの容量がさらにでかくなるとそれに伴ってスマホ内で完結する人も増えるはずなので、そしたら需要も増える...かもしれません。

開発期間

開発日誌を書いてなかったころのやつなので不明ですが、ソースコードのタイムスタンプからすると 2014/3/25 あたりから作っていたような記録があります。レビュー待ちを 1 週間として、3 週間くらい?

技術的な解説

ユーザがスタートボタンを押すと、まず Social framework の SLRequest.performRequestWithHandler でツイートを取得します。

並行して、ALAssetsLibrary.enumerateGroupsWithTypes と ALAssetsGroup.enumerateAssetsUsingBlock を使ってカメラロールから写真を全部リストアップします。
そのうち日付条件にマッチするものだけ取り出して、指定した長さになるように使用する画像と動画をピックアップします。

ピックアップの方法としては、過去のサマリーということで、対象となる日時範囲に対してなるべく均等に写真や動画を採用するようになっています。

例えば「去年の写真や動画を10秒の動画にする」場合で、去年の 1 月に 100 枚, それ以降の月に 10 枚ずつ写真を撮った場合、1 月のものが他の月の 10 倍多く採用されるんではなく、なるべくどの月からも同じ枚数採用するようにする、という動作をします。ただし、そもそも写真が少なければ 1 月のやつが結果的に大量に採用されます。

具体的には、日付条件にマッチする画像や動画すべてを前から見ていって、直前に採用したものの時刻から Interval 秒以上なら採用する、を繰り返して出来上がる動画の長さを求めるルーチンを Interval について二分探索して、動画が指定した長さになったときの配置を採用するというロジックになっています。

ということで、時間でなるべく均一にサンプリングすることで、自分は平均的には何してたんだろうというのが分かる仕組みになっています。

また、写真に含まれる GPS 情報を CLGeocoder.reverseGeocodeLocation で地名に変換して、K-means 法でクラスタリングして写真や動画を何個かのクラスタに分類しておきます。

...なんというかオーバースペックな気もしますが、ある程度近いところで撮った写真はまとめて「石垣島」とか「港区」みたいなそれを代表するような名前を付けたかったものと思われます。あとは全部同じ国なら国情報は描画しないようになっていたりもします。

ピックアップしたら、あとはいい感じにじわじわズームIN/OUTしながら出力映像に貼り付けて、ツイートや GPS 情報も合成していきます。
動画と音声のフェードイン/アウトも加味して AVAssetWriter とかで出力します。

結構込み入った動画生成処理を書いたので、今後何かに使いまわせるといいな〜と思います。

例えば自分のツイートや任意のタイムラインをテンポよく次々と画像化して動画にする、とか?

写真や動画はかなりプライベートな内容を含むだろうからハイライト動画も public には共有したくないだろうけど、公開ツイートであればハイライト動画も公開できるだろうから、ありかもしれません。作りたいアプリの TODO リストに追加ということで。

このアプリを作った頃は一般ピーポーは Twitter に動画をアップロードできなかったはずで (2015年1月に Twitter Video リリース)、今ならもっと気軽にネタ動画作成→投稿できる環境にある気がします。

以上、「97days」の紹介でした。




2016/11/09

【アプリ紹介】1コマまんが


今日は 2012/11/15 に公開した「1コマまんが」の紹介です。




こんなアプリ

吹き出しにテキストを入れるだけでちょっとした1コマまんがが瞬時に作れて、共有もできるアプリです。

キャラクターやシチュエーションはいくつか用意されている中から選べます。

吹き出しもキャラクターも自由に拡大縮小、移動できます。









開発の経緯と今後

ちょっとした出来事をまんがで気軽に表現したいなと思って作りました。

Webサービスで作っていた時期もありましたがもうスマホだろうということで乗り換え。

今後の発展としては、選べるイラストを増やすとか、流行ってるハッシュタグなど、あるテーマについてまんがが作れるようにするとかかなぁと思っています。

開発期間

開発日誌を書いてなかったころのやつなので不明ですが、ソースコードのタイムスタンプからすると 2012/10/18 あたりから作っていたような記録があります。レビュー待ちを 1 週間として、3 週間くらい?

技術的な解説

特別凝ったことはしてないです。UILabel や UIImageView を作ったり動かしたりして、共有するときには CGLayer.renderInContext で画像化して UIActivityViewController を呼び出します。

ちなみに、アプリ名は「1コマまんが」ではありますが、2 コマ以上のまんがも作れます。

なんというか、技術的にはなんでもない感じです。

以上、「1コマまんが」の紹介でした。




2016/11/08

【アプリ紹介】クロスわ〜ず


今日は 2014/3/15 に公開した「クロスわ〜ず」の紹介です。



こんなアプリ

全 695 問のクロスワードです。

制限時間はございませんので、すきま時間に、旅のお供に、どうぞごゆっくりお楽しみください。




開発の経緯

なんかこう、コンピュータっぽいことをして作ったなぁ、みたいなアプリを作りたいなぁと思ったのがきっかけです。

コンピュータっぽいというのは、ここではアルゴリズムを 1 回書けば大量のデータに対してほぼノーコストでそれを適用できちゃう、というあたりです。

おー、みたいな。

あとは、世の中には暇な人が相当数存在しているだろう、というファンダメンタル予想。

開発期間

開発日誌を書かなかったっぽいので明確ではないですが、ソースコードのタイムスタンプを見ると 2014/3/1〜3/9 あたりに更新されているので 9 日間くらいと思われます。

技術的な解説

Wiktionary から単語の読みと説明を抽出して、それを元にちゃちゃっとクロスワードを生成してアプリに組み込んでいます。

まずデータ取得部について。

Wiktionary から全ページの最新版のダンプ(jawiktionary-YYYYMMDD-pages-meta-current.xml) を落としてきて、SAX で parse します。
これがまた XML になっているようでなっていないので困ったものです。具体的には以下のような page 要素がだーっと並んで 250MB くらいのファイルになっています。

どういうことかと言うと...



text 要素がなかなかキてます。しかも単語ごとにいろんなバリエーションがあります。
なので、心折れそうになりながらも、ひたすら泥臭く解析します。

parser handler はこんな感じ(抜粋)。Ad hoc 楽しいめう!



こうしてなんとか (単語の読み, ヒント)[] が揃います。これを pickle にしておきます。今やるなら JSON にするところです。


そしたら今度はクロスワード生成部分です。

まず (単語の読み, ヒント)[] をシャッフルして、適当な大きさの白紙の問題ボードを作っておきます。

あとはひたすら、単語の置き方を全列挙してその中から 1 つランダムに選んで置いていきます。

単語の置き方とは、単語を置いた時ボードからはみ出なくて、置こうとしているところに既に違う文字や同じ方向に置かれた単語に含まれる同じ文字が置かれていなくて、これまで 1 個も置かれていない、または置こうとしているところに既に今回置く方向と直行する方向に置かれた単語の一部である同じ文字が置かれていてるようなものが 1 個以上あって、置こうとしている単語の周りのマスが既に置かれた同じ文字の所以外すべて空白であるような置き方 (x, y, direction) のことです。

意外とややこしいです...。

単語が 6 つ以上置けたらクロスワードが 1 問できたことになるので、実際に使われている大きさにボードをリサイズして記録します。で、ボードを空にして次の問題作成に移ります。

置き方がなくて詰んだ場合は使用単語を後ろにまわしてから再試行します。
未使用単語の残りが少なくなってくると何回やっても詰むことがあるのでそういう単語は捨てます。

よく覚えていないですが、695 問の生成に 30 秒くらいかかった気がします。この程度で終わるなら高速化は不要ですね。
問題セットが出来上がったら problems.js に出力します。

こんな感じ。



ということで、コンピュータっぽいことをして作ったなぁという実感が湧いてきます。

UI 部分については、ちとチープさが否めない感があります。これは今後の課題です。

以上、「クロスわ〜ず」の紹介でした。



【アプリ紹介】ちょっと読書


今日は 2014/11/06 に公開した「ちょっと読書」の紹介です。



こんなアプリ

160人の文豪が、自分達の小説計 400 作品以上を自ら断片的につぶやく、ツイッター風の読書アプリです。

夏目漱石や森鴎外、宮沢賢治など有名どころは一通り揃っています(感じ方には個人差があります)。

気に入った一節があったらSNSなどでシェアすることもできます。



小説の最後までつぶやいたらまた最初に戻ります。文豪たちは毎日不定期につぶやくので偶然面白いサムシングと出会えるかもよ、というわけです。

作者のアイコンをタッチすると Wikipedia のページが開きます。作品一覧のページでは気になる作品をフォローすることができます。

てかそれツイッターbotでいいんじゃね?という気持ちも僅かばかりありますが、一応ですね、ちょっと読書ならネットに繋がってなくても読めるしわざわざフォローしなくても最初から読めるし、...まあとにかく、作ってみたかったんですよ。

開発の経緯とこれから

隙間時間で受動的に読めて意外な発見がある読書アプリが欲しかったのがきっかけです。

本を読み始める動機として、本屋をウロウロしてちょっと読んでみて良かったからとか友達からのおすすめとか書評ブログを見たとかいろいろあると思いますが、それ以外、例えば「なんとなく本文の一部が流れてきたけどなんか面白そう」みたいな仕組みが作れたら意外な本との素敵な出会いが待っているかもしれない、といったところです。

データは、権利的に問題ないやつということで青空文庫の作品のうち著作権が切れているものを使うことにしました。

で、作ってやってみた感想としては文脈を多少なりとも理解するには 140 字は足りないなというのと、あと古い文体の本が多くていまいち興味をそそられない、あたり。

今後の展開としては、もうちょっと最近の本とか雑誌、ブログとかが流れてくるようにできたら面白いんじゃないかなあと思っています。例えば RSS フィードと組み合わせるとか、カクヨムで活動している作家さんの作品宣伝ツールの 1 つとしてちょっと読書に流してもらうとか。

ランキングだけだといまいち未知との出会いがないし、かといって新着はすぐ流れていっちゃうから困るなあみたいな方がいて、なんかコラボできたら楽しいなあと思っています。

開発期間

2014/10/11(Sat)〜2014/10/15(Wed) の 5 日間

データ取得/整形とそこそこ凝った画面ということで少し手こずりました。


技術的な解説

まずはデータ取得/整形です。python スクリプトを書きました。青空文庫のランキングデータを DL して parse し、そこから図書カードを DL して parse し、そして作者の wikipedia へのリンクやアイコンを取得し、なんと XHTML の本文を DL して頑張ってタイトルや作者名を抽出します。

<meta name="DC.Title" content="坊っちゃん" />

だったり

<h1 class="title">詩集〈月に吠える〉全篇</h1>

だったりまちまちなので、"BE ADHOC!" なる勇ましい掛け声が脳内をこだまします。

さらに本文の読み仮名などのマークアップを消して、115字以内のきりがいいところでカットします。

// 115文字で切る.
// できるだけ句読点 (,.、。)で切るが, その結果50文字以下 or 116文字以上になってしまうようならやむなく115文字で切る.
// 改行が6つ出現したらそこで切る.

こんな感じのコメントが発掘されました。

そしたらマクロ呼出し形式でデータを出力します。以下のような感じです。


BEGIN_BOOK()
AUTHOR("ツルゲーネフ")
TITLE("はつ恋")
WIKIPEDIA_BOOK_URL("")
WIKIPEDIA_AUTHOR_URL("http://ja.wikipedia.org/wiki/%E7%A5%9E%E8%A5%BF%E6%B8%85")
AUTHOR_IMAGE("author_photo_0006.png")
PUBLISHER("青空文庫")
BEGIN_CONTENTS(782)
CONTENT("[#ページの左右中央]\n\n\nP・V・アンネンコフに捧げる\n\n")
:
:
これをこんな感じで include してデータ化します。

#define BEGIN_BOOK() { Book* book = Book.alloc.init; book.ID = (int)_books.size();
#define AUTHOR(s) book.authorName = @s;
#define TITLE(s) book.name = @s;
#define WIKIPEDIA_BOOK_URL(s) ss=@s; if(ss) book.wikipediaBookURL = [NSURL URLWithString:ss];
#define WIKIPEDIA_AUTHOR_URL(s) ss=@s; if(ss) book.wikipediaAuthorURL = [NSURL URLWithString:ss];
#define AUTHOR_IMAGE(s) book.authorIconURL = authorImage(@s);
#define PUBLISHER(s)
#define BEGIN_CONTENTS(n) book.contentsOffset = contentsOffset; book.contentsSize = n;
#define CONTENT(s)
#define END_CONTENTS() contentsOffset += book.contentsSize;
#define END_BOOK() /*cout<<"ct.size "<<book.contentsSize<<endl;*/ _books.push_back(book); }
#include "books.h"

ただし本文までこの形式で初期化したらたしかコンパイルがやたら遅くて困ったので本文だけは const char* theContents[] にすべて格納するようになっています。

そしたらデータが 150MB になってしまい大きすぎて困ったので、減らす仕組みも用意しました。データサイズは減らしたいけど収録する作品数は最大化したかったので、あるしきい値以下のサイズの作品だけ収録するようにして合計で指定したサイズ以下になるように二分探索してしきい値を決めるなどして、402 作品収録、データサイズ 21MB ほどに収めました。

各作者によるつぶやきのタイミングは、ランダムに見せかけて実はすべて決まっています。とはいえ明らかにパターンが分かってしまってはおもしろくないので 1 日 86400 秒のうち何秒目につぶやくかというつぶやきパターンを何種類も用意しておいてうまいこと不定期に見せかけるということをしています。実のところ、フォロー集合さえ決まれば、ある時刻における最新のタイムラインはすべて求まるようになっています。とするといろいろ実装が楽なのです。

あとはそれっぽい UI をいくつか作って繋ぎ合わせました。

無限スクロールが意外と手こずった気がします。UIScrollView の表示領域に加えて画面の高さ 5 個分の範囲内のつぶやきについてだけ UIView を配置するようにして、範囲に入ったら作成、外れたら破棄する制御をしているわけですが、新たに表示すべきデータが現れたとき、一度に全部を addSubview すると数ミリ秒かかってスクロールがカクつくし、かといって UI に関することなので別スレッドでやるわけにもいかず、結局 0.1 秒間に 3 回までしか addSubview しないようにしてヌルヌルスクロールを実現しました。


以上、「ちょっと読書」の紹介でした。








2016/11/07

【アプリ紹介】電飾カメラ / IllumiCamera


今日は 2016/01/12 に公開した「電飾カメラ」の紹介です。





こんなアプリ

夜景にネオンのような電飾を合成した動画を作るアプリです。

アプリを起動するとカメラ映像の上にほぼリアルタイムで電飾が合成されます。

シャッターを押すと、その時の風景に対して5秒分の動画が作られ、アルバムに保存されます。









▼普通の景色を電飾でキラキラさせるカメラです
▼5秒の動画が保存できます
▼暗めの人工物を写すのがおすすめ
▼ループビデオとしてVineに投稿しよう

アプリ説明にこんなこと書きましたが、Vine 終わっちゃいますね〜。


開発の経緯

詳しくはディスコマシンの紹介記事に書いた通りですが、前から作りたかったやつです(適当)。

あ、思いだした、元はと言えば休暇で香港に行った時、Symphony of lights という高層ビル群が音楽に合わせてピカピカ光ったりレーザービームが出まくる派手なショーを見たのがきっかけです。ああいうのをアプリで再現できたら面白かろうということで作りました。

ちなみに Symphony of lights は毎日 20 時からやっているので香港に行ったら是非見てみてください。

ちなみに香港といえば、毎日正午に撃たれる大砲「午砲(Noonday Gun)」も外せません。これは元々 Jardine Matheson 社が銅鑼湾に入港した自社のエグゼクティブを歓迎するために祝砲を撃っていた所、1860 年に香港に赴任したてでその習慣を知らなかった英国海軍将官が一民間企業が祝砲を撃つなんぞケシカラン、罰として以後ずっと毎日正午に時砲を撃つべし、と命令して行われるようになったのが今でも残っているものだそうです。(1941〜1947の間は日本による占領のため中断)

話を戻しまして、電飾カメラでは Symphony of lights のような音楽を鳴らすところまではできなかったですが、後に出した「ディスコマシン」ではアガる音楽が付いたりより派手になったり、リアルタイムに動画生成できるようになったりといろいろ改良されて今に至ります。

開発期間

開発日誌によると、2015/12/19(Sat) 15:58 に着手開始とあります。

OpenCV on iOS が初めてだったのでやや手こずったものの、19:46 にはカメラ映像を輪郭データ Vector3[][] にしてダミーの点灯パターンで描画して映像と合成するところまで完成、21:00 には人間の感性を揺さぶる電飾点灯アルゴリズム「IlluminationEngine™」が完成したようです。

翌日は起床〜 14:00 と 18:00 〜 21:30 で作業、21:40 にレビュー提出完了。その後スクショやビデオの準備。

Apple レビューチームが 12/22〜12/29 と冬休みに入ったのと iPad で落ちるバグがあって再提出したので公開は年明けの 2016/1/12 になりました。

ということで、メインの開発期間としては 2 日間、実質 13 時間くらいでしょうか。

技術的な解説

カメラ映像に対して OpenCV で輪郭検出をして、ノイズっぽい輪郭を除去した上で今回独自開発した人間の感性を揺さぶる電飾点灯アルゴリズム IlluminationEngine™ により点灯パターンを算出し、ほぼリアルタイムで OpenCV の API により輪郭を描画します。

フレーム間で同じ輪郭に対して異なる色を出力してしまうと脈絡のないチカチカした映像になってしまうので、そうならないようにするなどわりかし考えることはいろいろありました。

OpenGL を使うともっといろんな表現が高速に描画できるだろうなあと思いつつ、それは後でということで妥協しています。

当時は ReplayKit が出たばかりでその存在を知らず、わざわざオフラインで動画生成しています。そうすると生成中のくるくるやプログレスバーとか中断ボタンとか完了後の共有ボタンとかいろいろ作る必要があって今から振り返ると結構面倒ですね。

当時でもリアルタイムに動画出力することは理論上できたはずですが、輪郭検出から描画までの処理が結構重かったのでそこまで頑張る必要もなかろうということで軽やかにボツに決定。

動画出力には AVAssetWriter などの API を使っています。結構面倒な API ですが、以前作った分身カメラで使ったルーチンをライブラリ化していたのでそれを使い回せました。

分身カメラについてもそのうち紹介記事を書こうと思います。

以上、「電飾カメラ」の紹介でした。










2016/11/05

【アプリ紹介】よいしょカメラ - お世辞だって、いいじゃないか

今日は 2015/12/20 に公開した「よいしょカメラ」の紹介です。



こんなアプリ

独自開発した DeepRandom™ 技術により年齢推定できちゃう賢いカメラアプリです。じゃなくてジョークアプリです。



他にも、左右スワイプすることでおちんぎんヘソクリかわいさ総資産友達の数留年回数を推定することができます。

ともだち同士とかで使って頂けるとよいかと思われます。






最後の 2 枚は今年の GW にベトナムのホイアンを訪れた時の写真です。


開発の経緯

オーシャンズ 13 にて、最高の人工知能セキュリティ「グレコ」に守られたカジノをオーシャンたちが攻略して客にたんまり儲けさせる場面で客の映像に儲け額を AR で重ね合わせて描画してたのが着想のきっかけです。

8 年前なんですね。結構寝かせていたネタでしたが、開発開始からレビュー提出までの期間は 10 時間でした。このアプリもタイムアタック案件。

開発日誌によると、2015/12/13(Sun) 14:43 ころカフェで開発開始、自宅で夕食(鍋)を挟んで翌日 0:44 提出完了となっています。

ちょっとそこ、開発日誌とかつけてんのエモいとか言わないでください。

技術的な解説

カメラからリアルタイムに取得した映像に対して OpenCV の CIDetector.featuresInImage で顔認識をして、その位置に黄色い枠と DeepRandom™ エンジンにより算出された各種推定値を描画します。


無駄にスマホの横画面(Landscape)モードに対応ようとしたため、スマホの向き 4 通りすべてについて顔検出における上方向 (CIDetectorImageOrientation) を正しく指定しないと顔認識できなかったり、AVCaptureVideoPreviewLayer に表示される画像と実際にデータとして取得できる画像のサイズが合わなかったりして苦労しました。
結局時間がないので 4 通りそれぞれ場合分けしてパラメータを設定したりしていました。

case UIDeviceOrientationLandscapeLeft:
    // なんか逆だと思うんだがこっちじゃないと認識しない
    exifOrientation = PHOTOS_EXIF_0ROW_LEFT_0COL_BOTTOM;
    break;

こんなコードが残ってたりして、1 年前の心の葛藤を思い出さずにはいられません。

シャッターが押されたらその時の UIImage を iOS アルバムに出力します。一応ガイドライン的なものを尊守すべく、シャッターを押したらわざわざシャッター音を鳴らしています。えらい。

よくアプリ内で撮影した写真の一覧を見る画面が出たりしますが、そういうの面倒なのでアルバムアイコンを押したらアルバムアプリに飛ぶようにしました。ちょうど 2015/9/16 にリリースされた iOS9 から「前のアプリに戻る」ボタンが出るようになっていたのでこの仕様でOK。アルバムアプリに飛ぶには UIApplication.openURL で "photos-redirect:" を開けばよいです。簡単です。


DeepRandom™ エンジンの開発には、中でも特に苦労させられませんでした。Random だけに。人間が使ってほっこりするようなアプリにしたいというコンセプトもあったので、ちょっと若めに推定するようにできています。

以上、投げやりですが「よいしょカメラ」の紹介でした。





【アプリ紹介】旅してQ!: スタジオと中継がつながっています

今日は 2016/11/4 に公開したセルフィビデオアプリ「旅してQ!: スタジオと中継がつながっています」の紹介です。



こんなアプリ

あなたは旅のリポーター。スタジオのアナウンサーと中継でつながってスタンバイ中です。さて次のコーナーは世界各地からの旅行リポートをお届けする「旅してQ!」。いよいよ始まります。

あなたの様子が全国放送され、左下にはスタジオのアナウンサーが PinP で小さく映っています。それではリポートをどうぞ!

という設定で、テレビ中継っぽい自撮り動画を撮影する新しいスタイルのセルフィビデオアプリです。

中継中は、画面下のアイコンを押すと拍手や歓声などテレビのバラエティーっぽい効果音を鳴らすことができます。自撮りで滑ったら効果音で流してしまいましょう。

有料版なら、「がっかり」「えー?!」「爆笑」など、流せる効果音の種類が増えます。

中継(撮影)が終わったら、SNSで旅行先にいることをアピールしてもいいし、友達や恋人や親に送ってもいいし、単に保存しておいてあとで見返してもOK。

開発の経緯

ディスコマシン熱々の料理の構想中に、これ同じデータフローで自撮りも行けるんじゃね?と気付いたのがきっかけです。

それに、今 YouTuber とか流行ってるし、その中で放送ネタに困ってる人もいるはずだとか、自撮りは恥ずかしくてできないという人でもアプリが質問してあげてテンプレを提供してあげれば自撮りの敷居も低くなるだろうというファンダメンタルもあり、作ってみました。

...と書いてたら関連ネタを思いつきました。そのうち作ろうと思います。

技術的な解説

カメラ映像を表示する AVCaptureVideoPreviewLayer の上に、アナウンサーのおねえさん画像やテロップ、スタッフの指示を描画して、画面録画フレームワークの ReplayKit で動画に出力しています。

AVAssetWriter みたいないかにも動画出力ガチ勢みたいな API は一切使わず、単に ReplayKit の RPScreenRecorder.startRecordingWithHandler とかを呼んでいるだけです。

AVAssetWriter で出力するとそのままではどんな仕上がりになるのかわからんので、プレビューみたいな UI が欲しければ自分で作らないといけないわけですが、ReplayKit なら画面に出た内容がそのまま記録される (WYSIWYG) と分かっているのでユーザ体験としても分かりやすいし開発が簡単なのでいいことばかりです。

2016 年に WYSIWYG という言葉を使うとは思わなかったです。

ReplayKit だと記録したくないものがある場合や画面の一部だけ出力したいということは今の所出来ないですが、そのくらいならそのうち公式に対応してもおかしくないでしょう。そしたら正方形動画とかも作れるし、プラットホームとしてもできることの幅が広がって良いことばかりでありましょう。

なんかもういろいろ応用が効いて簡単なので、馬場タクシー3Dディスコマシン熱々の料理旅してQ! と最近はやたら ReplayKit ばかり使っています。

アナウンサーの声は Mac の say コマンドで喋らせました。

ちなみに。アナウンサーのおねえさんは馬場タクシー3Dに出てくるガチャのおねえさんと同一人物です。背景のアルファ化がめっちゃ甘くてすいません(笑)

以上、旅してQ!の紹介でした。




2016/11/04

【アプリ紹介】熱々の料理: 例えるならコーヒーから湯気を出そう

今日は 2016/10/26 にリリースした 「熱々の料理: 例えるならコーヒーから湯気を出そう」 の紹介です。



こんなアプリ

カメラ映像に映ったコーヒーなどの料理に対して湯気を合成することであったか〜い感じにする(だけの)アプリです。
有料版では映像の保存ができます。

サンプル動画。



開発の経緯

ディスコマシンでスモークを出す機能を作ってたら、これコーヒーから湯気を出すのに使えるんじゃね?と思ったのでスピンオフアプリとして作りました。

とある日曜日、20時の NHK 大河ドラマ「真田丸」視聴までに作って帰るという目標でカフェにて 17:30 からタイムアタック作業開始。ん〜、後から考えると、そもそも作業開始が遅い気がしますね。

ディスコマシンのソースをコピペして不要な機能を削ってスモークを中心から出すように変えたりして 19:00 には有料版/無料版共に機能完成、そこからアイコンとスクショを作って、iOS dev center で AppID とか登録してアプリ概要を書いて 2 種類リリースビルドして iTunesConnect で 19:33 審査提出、ぎりぎり 2 時間で間に合いました。

ヘルプは UIWebView で外部サイトを表示しているだけなので審査待ちの間にゆっくり作成。

高校生の時は センター試験英語に出てきたゲーム を 2 日で作ったりしていたので、昔からタイムアタックは好きだったようです。

技術的な解説

馬場タクシーやディスコマシンで使っている自作の煙描画ライブラリを使って、カメラ映像の上に画面中央からほのかに立ち昇る湯気を描画しています。

コーヒーや料理をどうやって認識してるの?と友達に聞かれましたが、認識はしてなくて人間がコーヒーに合わせてスマホの位置や角度を調整するようになっています。

コンピュータと人間の共同作業であります。

ちなみに審査用にスクリーンショットを 2 枚、それを iPhone/iPad 用、日本語英語用、合わせて 4 種類ずつ合計 8 枚の画像を作ったわけですが、これまでにいくつもアプリを作っているのもあってその辺はかなり効率化されています。

具体的には、日本語/英語 2 種類の SVG ファイルを Inkscape で作っておいてスクリプトで iPhone/iPad 用のサイズで分けて画像にエクスポートするような仕組みがすでにあり、それを使ったのでスクショ作成はそこまで面倒ではなかったです。むしろアップロードが面倒。

アイコンを作るパイプラインも結構効率化されています。
iOS の場合 20 29 58 87 40 80 120 60 120 180 76 152 512 167 57 114 50 100 72 144px など実に様々な大きさのアイコン画像を用意する必要がありますが、1 コだけマスターアイコンとして SVG ファイルを作っておいて、それを 1024x1024 画像にエクスポートしてから ImageMagick とスクリプトで各サイズに縮小したり、起動画面やホムペ(死語)用に角丸の部分が透明になるように自動加工したり、さらに生成したアイコン画像を xcode の Assets ファイルに自動コピーしたりする仕組みを過去に作ったので、それを使って面倒な作業がコマンド一発で終わるようになっています。

ということで、技術的な解説というかアプリ作成効率化の話がほとんどでした。

以上、熱々の料理: 例えるならコーヒーから湯気を出そう の紹介でした。





2016/11/03

【アプリ紹介】ディスコマシン / DiscoMachine

今年作りたかったものがだいたい開発し終わって落ち着いてきたので、作ったものについていろいろ書いていきたいと思います。

まずは 2016/10/24 にリリースした ディスコマシン について。


こんなアプリ

ディスコマシンは、スマホのカメラで写した夜景などの映像にディスコっぽいグラフィックといい感じの音楽を合成して楽しむアプリです。

有料版では画面と音を録画して保存したり、SNS で共有できたりします。
分野としては拡張現実(AR)あたりでしょう。

例えば、夜の銀座4丁目交差点でアプリを起動するとこんな映像になります。

開発の経緯

このアプリ、実は結構前からこういうの作りたいなぁと思っていました。

その記録が 2014 のインタビュー記事 アプリ開発者に訊く! ~ 「馬場タクシー3D」 に残っています。 今後出すつもりのアプリは?という質問に対して「いつもの風景がズンチャカピカピカみたいなものを作る予定です。」と答えたやつ、あれがディスコマシンです。

作りたいなぁ作りたいなぁと思いつつも 馬場タクシー3D の方がもっと作りたかったので、しばらくはなかなかガッツリ時間を取って作れなかったわけですが、2016年秋に馬場タクがバージョン 4.5 になってようやくそこそこ満足する形に落ち着いてきたのでディスコマシンに着手し、休日のカフェや休暇で訪れたセブ島のビーチで 日の出タイムラプス動画 を撮影したりしながらガリガリ開発していました。

発想のきっかけとしては、クラブでいい感じの音楽や演出を見ると楽しいけどスマホで AR にしたらもっと気軽にそういうのが体験できていいんじゃね?的な感じです。

アプリによって時間制約と移動コストがなくせるよねみたいな感じで。 ただスマホの画面はとても小さいこともあって臨場感はまだまだですな。家のあらゆる壁がディスプレイになったり VR が安く普及したりすると、また違う体験になるかなーと思っています。

ちなみに、いきなりディスコマシンを作ったわけではなくて、1年弱前の 2015 冬には 電飾カメラ という似たようなアプリを作っています。電飾カメラについてもそのうち記事を書こうかなと思っています。

技術的な解説 

技術的にはたいしたことないというか、すでにある技術を組み合わせた感じです。

まずカメラ映像をリアルタイムに取得して、OpenCV で輪郭とコーナー検出をします。

同時にアプリ組み込みの音楽やユーザの iTunes ライブラリから選んだ音楽をデコードして再生しつつ、raw data を DSP で FFT します。

検出した輪郭情報 Vector3[][] とコーナー情報 Vector3[] と FFT データ float[] を、今回開発した人間の感性を揺さぶる DiscoEngine™ により解析し、OpenGL ES 2.0 を使っていい感じに輪郭やレーザー光線やピカピカ光ってる感じの画像やスモークを描画します。

ちなみに、電飾カメラでは撮った写真をキラキラデコって動画として出力することができますが、そのときは出たばかりの iOS ReplayKit framework の存在を知らなかったので 1 フレームごとに UIImage を生成して AVAssetWriter を使って動画を生成していました。

今回ディスコマシンでは画面に出たものがそのまま動画になる ReplayKit を使ったので、そのあたりを作らなくて済んだのでめっちゃ楽でした。 ReplayKit は生放送にも対応したようだし、アプリによっては独自でそのあたりを作り込まなくて済むのでいろいろ可能性があると思っています。

ということで、ディスコマシンの紹介でした。