hirax.net::inside out

最新記事(inside out)へ  |   年と月を指定して記事を読む(クリック!)

2017年4月 を読む << 2017年5月 を読む >> 2017年6月 を読む

2017-05-20[n年前へ]

スマホ(BLE)から動かせる街中スナップ用の(Ricoh Theta用)自動制御アームで特殊映像を撮ってみる  share on Tumblr 

スマホ(BLE)から動かせる街中スナップ用の(Ricoh Theta S用)2軸自動制御アームを作ってみる」を南国バンコクに持ち込んで、この撮影機材をリュックの中に詰め込んで、自転車で街中をウロウロしながら特殊撮影をしてみました。特殊撮影というのはどういうことかというと、異なるたくさんの視点から撮影した全周画像をもとに3次元空間を再現したり、その3次元空間に光が注ぐ世界の中を歩いてみたり…という実験です。

 リュックから大型三脚とBLE経由制御の駆動ユニットを組み立てて、Ricoh Theta Sを取り付けるまで、慣れれば1分で完了します。そして、バンコクの通りに立てた特殊機材の近くから、iPhone 経由で駆動制御と撮影をしてやるのです。数十枚〜百枚弱の撮影をおよそ5分弱の間に行うのです。

 そんな撮影をしたら、カメラの周りに存在した3次元空間を再現するための計算をCPUとGPUをぶん回し行います。あるいは、そんな世界に差し込む光や反射する光をガウス的に捉え再現するための計算を、やはりCPU・GPUをぶん回して行うのです。…そんなことをするこで、色んな映像を作り出すことができます。

 たとえば、下の動画はBTS(バンコク・スカイトレイ)のスラサック駅近くにある、中華系の墓地の Tae Chew Association of Thailand で撮影した72枚の全円周な画像群から生成した3次元映像です。この動画では3次元空間を1方向に向かい眺めているだけですが、再現されたデータ世界の中では、「一応」すべての方向に向かう風景が生成されています。

 といっても、こんな映像はとてもチープなのもまた確かです。けれど、そんな撮影画像であっても、「もう二度と見ることができない今の時代を撮影した」データであるような気もする…ので、こんな変な撮影を色々してみて残していこうかな、と思います。

スマホ(BLE)から動かせる街中スナップ用の(Ricoh Theta用)自動制御アームで特殊映像を撮ってみるスマホ(BLE)から動かせる街中スナップ用の(Ricoh Theta用)自動制御アームで特殊映像を撮ってみる






2017-05-18[n年前へ]

ディープラーニングによる姿勢推定openposeで「男子の夢な(衣服の下を透視する)妄撮カメラ」を作ってみよう!?  share on Tumblr 

 ディープラーニングによる単眼画像からの人物姿勢推定を行うコード OpenPose が公開されました。公開されたコードを使うと、画像ファイルや動画、あるいはWEBカメラで撮影された画像などを入力として、そこに写る人の姿勢(主要な関節の位置など)を推定することができます。姿勢推定の品質もなかなか素晴らしく、画像に写る人の姿勢が見事に写し出されます。

 画像から、人物の姿勢推定を簡単にできる…となると、「中二男子の夢的なこと」「あの頃夢見た妄想」をやってみたくなります。つまり、女の子の服の下をひたすら妄想し、その下の姿を透視する男子の夢の実現です。

可愛い女の子の服の下はどんなだろう……?そんな中学男子マインドを持ち続けたまま大人になった男たちへ。
妄撮

 手順はそれほど難しくありません。少なくとも、男子禁制の世界を手に入れる夢に向かう力があれば、実際のところとても簡単です。

 まず、google画像検索から任意のキーワードで画像を収集することができるgoogliser.shなどで、自由自在な「あなたのお好みスタイルに沿った人物姿勢画像」をダウンロードします。たとえば、下の例であれば、少し胸が大きめな立ち姿勢の(そして生まれたままの姿の)人物画像が集まります。もちろん、「どちらかと下着くらいは着ていて欲しいんだボクは」というのであれば、そうした検索語句でコマンドを走らせれば一発です。

./googliser.sh --phrase "naked body boobs" --title 'nakedBodyBoobs' --upper-size 900000 --lower-size 2000 --failures 40 --number 100 --retries 3
 次に、肝心要の「妄想したい画像」も用意しておきましょう。すべては、衣服の下に隠されたその姿を透視するためなのですから、その画像は何より一番大切です(好みに合わせてね)。

 そして、openpose を使えるようにした上で姿勢推定のテストをしてみます。たとえば、下のコマンドのような具合で動かせば、ディレクトリ(sampleImages)に入ってる画像群に写る人の姿勢が、YAML形式でposesディレクトリに生成されるようになります。

./build/examples/openpose/openpose.bin --image_dir sampleImages --write_pose poses/ --write_video result.avi

 ここまで来れば、あとはわずかにコードを書くだけです。妄想・透視したい画像・人物のYAML姿勢ファイルと、Google検索で集めた人物YAMLファイルを読み込み、妄想・透視したい人物の姿勢と類似する(妄想内容に近い)別の人物画像を見つけ出し、それらを中二男子の夢的な画像合成をしてやれば良いわけです。姿勢の類似性は、姿勢の大きさを適当に正規化し、向きも基準の方向を決めた上で、同じ関節どうしの距離を比較する、という具合で良いでしょう。そして、妄撮カメラ用途なら、胴体に近い部分の関節だけを計算に使うので十分でしょう(多分ね)。

 最期に、試しに書いたPython コードで確かめてみた妄想結果が、右上に二枚並べた画像です。男子の多くが夢見た妄想が、機械学習・ディープラーニング力により見事に実現しています。もちろん多少のズレが生じることも少なからずありますが、所詮は妄想、ズレがあっても・中味が全然本人と違っていても、「見えた気になれば良い」のです。

 妄想力だけで書いたコードはここに置いておきます。いつものように、何も考えず書いたコードなので、誰かの役に立つかはわかりませんが、jupyter notebookとpythonコードを置いておきます。また、妄想感度を高めるために、「紙・写真を破った感じで(こういうディティールは妄想満足度をアップさせるのにとても重要です)、その下の姿と画像合成する」処理を行うpythonコード中からマスク画像を読み込んでいます。その部分は、たとえば右に貼り付けたような画像を使えば良いかと思います。

 何はともあれ、妄想こそが発明の親。「こんなこといいな、できたらいいな」と思ったら、その瞬間に男の子は誰もがドラえもんになることができるのです。未来を描くのは、全てがいつも妄想です。
 というわけで、「こんな娘がいいな、見えたらいいな」と心の中のドラえもんに念じたことがあるボクら全員のために、機械の力と妄想力をフルに使い、ディープラーニングによる姿勢推定openposeで「男子の夢な妄撮カメラ」を作ってみました。

こんな娘がいいな、見えたらいいな。
あんな夢、こんな夢、一杯あるけど…
みんなみんなみんな、叶えてくれる、
深層学習が叶えてくれる。

ディープラーニングによる姿勢推定openposeで「男子の夢な妄撮カメラ」を作ってみよう!?ディープラーニングによる姿勢推定openposeで「男子の夢な妄撮カメラ」を作ってみよう!?ディープラーニングによる姿勢推定openposeで「男子の夢な妄撮カメラ」を作ってみよう!?ディープラーニングによる姿勢推定openposeで「男子の夢な妄撮カメラ」を作ってみよう!?






2017-04-30[n年前へ]

スマホ(BLE)から動かせる街中スナップ用の(Ricoh Theta S用)2軸自動制御アームを作ってみる。  share on Tumblr 

 先週、Ricoh Theta用の極座標自動アームを作った。それを旅先で持ち歩き・街中で2軸アームを 動かしつつ気軽なスナップ写真を撮るために、今日は「ステージ制御をスマホ(iPhone)からできる」ようにしてみました。作戦は、iPhoneとアーム制御ボード間をBluetooth(BLE)で繋ぎ、iPhone上で動くPython環境(Pythonista)から制御アームとRicoh Theta Sを同期制御するという仕組みです。

 先週組んだアームはMakeblockのパーツを使っているので、その制御に使ってる(Makeblock製の)ArduinoボードにBluetooth I/Fを繋ぎ、ドキュメントとiOSアプリのLightBlue Explorerで制御ボードにアクセスしてみると、servicesのFFE1中にあるcharacteristics FFE3 に書き込みを行えば、制御ボードに情報を渡すことができることがわかります。…というわけで、「iPad + Pythonista(iOSで動くPython) + BLEで、Genuino101のLチカをしてみた。」を参考に、Makeblock(Arduino UNO)ボードに(適当に俺ルールで決めた5byte一組の)コマンドをiPhone(Pythonista)から送りつけ、そのコマンドをもとに2軸アームを動かしてみることにしました。

 というわけで、スマホから制御できる「Ricoh Theta S+制御アーム」を持ち歩き、山道で撮影した(円筒表面上の48枚の)画像から、試しに生成してみたた3次元風景が下の動画です。Ricoh Theta S自体は、全天周撮影を行うカメラですが、それを閉曲面状の複数点で撮影することで、3次元な全天周世界を復元したり、周囲の見た目を再現したり(ライトフィールド)することができます。

 ちなみに、iOS Pythonista ( Python ) からの制御コードは、上記参考コードをもとにして、たとえば下のような感じにしています。

    def did_discover_services(self, p, error):
        for s in p.services:
            print(s.uuid)
            if 'FFE1' in s.uuid:
                p.discover_characteristics(s)

    def did_discover_characteristics(self, s, error):
        if 'FFE1' in s.uuid:
            for c in s.characteristics:
            if 'FFE3' in c.uuid:
                 self.myProcedureWithTheta(c)
その上で、(上記コードのmyProcedureWithThetaとしたような部分で)適当なコマンドや値をMakeblock Arduinoボードに渡す(そしてその情報をもとにアームのモータなどを動かす)ことで、持ち歩き用の自動制御アーム付き三脚のできあがり!というわけです。
self.peripheral.write_characteristic_value(
        c, cmd, False)
self.peripheral.write_characteristic_value(
        c, bytes([step]), False)

スマホから動かせる街中スナップ用の(Ricoh Theta S用)2軸自動制御アームを作ってみる。スマホから動かせる街中スナップ用の(Ricoh Theta S用)2軸自動制御アームを作ってみる。スマホから動かせる街中スナップ用の(Ricoh Theta S用)2軸自動制御アームを作ってみる。






2017-04-23[n年前へ]

Ricoh Theta用の極座標自動ステージを作ってみよう!(その心は、どちらもRなθと解きます)  share on Tumblr 

 これまで、今や誰もが持ち歩いているスマホを使った手持ち移動撮影で、大径レンズを取り付けたカメラにような画像を作り出してみたり(「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみよう!? )、あるいは、全天周を撮影することができるRicoh Theta Sカメラを使って、ありとあらゆる情報を手に入れてみようと遊んでみたりしてきました(Ricoh ThetaSで全天周/HDR/立体動画の撮影に挑戦してみるRicoh Theta S 撮影動画で3次元の世界を撮影してみよう!?)。

 今日は、それらの続きをやってみよう!というわけで、全天周カメラRicoh Theta用の極座標自動ステージを作って、いくつかの撮影&後処理を行ってみました。

 まず、左下は試行錯誤的に作っている(途中の)自動制御ステージです。ステージを動かして違う場所から撮影した写真を使えば、もちろん立体的な映像を作り出すことができます。…というわけで、試しに作った立体視用画像が右下の画像です。

 2つの視点から見た映像を並べれば立体的な映像を感じることができるのと同様に、複数視点からの撮影画像を解析すれば、立体的な世界を再現することができます。…というわけで、自動制御ステージに載せたTheta Sで撮影した画像から生成してみた3次元映像が、下に貼り付けた動画です。

 …と、Ricoh Theta用の極座標自動ステージを作りながら、ふとと気付いたことがあります。それは、もしかしたら、あまり目的思考がなく、Ricoh Thetaを使ったRθな極座標系ステージを作ってみたかっただけかもしれない…ということです。(その心は、どちらもRなθと解きます)

Ricoh Theta用の極座標自動ステージを作ってみよう!(その心は、どちらもRなθと解きます)Ricoh Theta用の極座標自動ステージを作ってみよう!(その心は、どちらもRなθと解きます)http://www.hirax.net/diaryweb/2017/04/23.html#10975http://www.hirax.net/diaryweb/2017/04/23.html#10975http://www.hirax.net/diaryweb/2017/04/23.html#10975






2017-04-18[n年前へ]

たった2枚のスマホ写真から、自動でリアルなCG素材を作ってみよう!?  share on Tumblr 

 スマホを使って、(スマホ付属のライト点灯有無による)2枚の撮影画像から対象物の素材情報(反射特性や凹凸分布)をキャプチャする研究があります。原理は単純で、一般的に照明光が方向性を持つ普通の環境下で撮影した写真からは、同じ方向を向く領域が抽出できるし、照明ライトを点けた写真からは、(撮影画像内の各領域に対する)照明方向と撮影方向がわかるので、それらを組み合わせると、色んな情報がわかるよね!という内容です。…その研究内容が、最近NVIDIAサイトで最近WEBサービス(Photo To Material: 2shot)化されました。

 これは面白そう!というわけで、使ってみた結果が下のようになります。左2枚の写真が、黒皮的な素材をスマホで撮影した画像で、右の画像がWEBサービス(Photo To Material: 2shot)で生成された素材データを使ってCGレンダリングした画像です。…わかりにくいかもしれませんが、たった2枚のスマホ撮影画像から、対象物の色や3次元形状などが得られていることがわかります。

 ためしに、畳をスマホで撮影して・その撮影画像から生成した素材データを使ってCGレンダリングを行ってみると、下の画像のようになります。…わかりにくいかもしれませんが、3次元情報や色やさまざまな情報が得られていることがわかります。

 処理可能な撮影対象は、(規則的である必要は無いのですが)似たような模様が繰り返されているパターンに限られます。けれど、目の前にある素材を「記録」して「CGなどで使ってみたくなる」ことも多い…かもしれません。そんな時、このNVIDIAのサービスはとても役立つに違いない!というわけで、もう少し遊んでみようと思います。

スマホ写真からリアルなCG素材を作ってみよう!?スマホ写真からリアルなCG素材を作ってみよう!?スマホ写真からリアルなCG素材を作ってみよう!?






2017-04-15[n年前へ]

続 OpenFOAMの流体シミュレーション世界、手持ちのスマホで没入体験してみよう!  share on Tumblr 

 少し前、大規模な流体計算シミュレーションを行った結果の中に、スマホをVRデバイスとして入り込む…というOpenFOAMの流体シミュレーション世界、手持ちのスマホで没入体験してみよう!(を書いた。これを作るにいたったキッカケは、「秋葉原の街中全体を空気流計算するのは面白い」「けれど、ふつうの人が持ってないヘッドマウントディスプレイだけでしか見ることができないのはツマラナイ!」「空気流れる空に向かって飛んでみたい!」というコメントをもらったことだった。

 このコメントは確かにその通りだ。1家に1台…ならぬ今や1人1台誰もが持っているスマホを使って流体シミュレーション世界に入り込む(没入体験する)ことができたなら、それは確かにとても面白いに違いない!というわけで、流体シミュレーション世界にスマホを使って没入体験するための作業をしてみたのです。

 「秋葉原の街中全体を空気流計算するのは面白いけれど、ふつうの人が持ってないヘッドマウントディスプレイだけでしか見ることができないのはツマラナイ!」というコメントがもっともなのと同じように、「空気流れる空に向かって飛んでみたい!」というコメントも、確かにその通りとしか言いようがありません。

 …というわけで、今日はその「空気流の中を飛び回りたい」という要望もに応えるための対応作業をしてみました。

 そんな作業をしてみたら、偶然というものは恐ろしいもので、まさに今日は『第64回オープンCAE勉強会@関東(流体など)』が会場【秋葉原】で開催されています。

 秋葉原を流れる空気を流体計算し、その場所に立ちVR/AR的に流体計算結果を眺めることができて、その秋葉原で今日まさに流体計算の集いが開かれている!?…というわけで、スマホで秋葉原空気流のVR表示を行う話を、今日は秋葉原で紹介してみました。

2017-04-08[n年前へ]

2人で対決する「決闘」、自分が生き残る確率は50パーセントで正しいか?  share on Tumblr 

 2人が対決する決闘、生き残る確率と殺される確率、一体何パーセント?…この確率問題が意外に興味深かったので、『2人で対決する「決闘」、自分が生き残る確率は50パーセントで正しいか?』を書いてみる。

2017-04-07[n年前へ]

OpenFOAMの流体シミュレーション世界、手持ちのスマホで没入体験してみよう!  share on Tumblr 

 以前、OpenFOAMを使ってシミュレーション計算した、秋葉原の街全体に吹く空気流。その時は、Oculusで没入的に眺めてみた。今日は、スマホで普通にVR没入体験できるよう、スマホ用アプリケーション化してみた。

 最初は、最近公開されたばかりのUnity 5.6のネイティブなVR機器サポートを使おうと思ったのだけれど、iOS向けのビルドでリンカエラーが出て回避できなかったので、Unity 5.5.3f1+Google VR SDK for Unity v1.0.3で仕立ててみました。

OpenFOAMの流体シミュレーション世界にスマホで没入体験






2017-03-29[n年前へ]

鎌倉大仏、十円玉を何枚で作れるか!?  share on Tumblr 

 数字と科学にこだわる歴史記事をこれから3ヶ月間書くことにした!というわけで、今日は「鎌倉大仏、十円玉を何枚で作れるか!?」を書く。

”10円玉で作ったら4億4500万円!青銅製の鎌倉大仏は、青銅の材料費だけなら1億3千万円!アルミニウムの1円玉で作ったら、6050万枚=6050万円ナリ!”

2017-03-27[n年前へ]

自由の女神・奈良大仏・鎌倉大仏で「銅メダル何枚作れるか」競技をすると?意外な順位の秘密とは!?  share on Tumblr 

 今日書いた記事は『自由の女神・奈良大仏・鎌倉大仏で「銅メダル何枚作れるか」競技をすると?意外な順位の秘密とは!?

 銅製・青銅製の彼らを溶かしてメダルを作って獲得メダル数はどうなるかを調べてみた。すると、その歴史的経緯や構造的経緯が見えてきたり…技術者「エッフェル」が自由の女神の構造設計をして、それが「エッフェル塔」に繋がっていることが見えてきたりする。

2017-03-19[n年前へ]

天下一品がもしも太麺だったら…(汁の粘度的に)女性人気が低いラーメン店になっていたに違いない!?  share on Tumblr 

 天下一品の麺は、ドロドロの粘度高いスープにストレートな細麺が使っている。今日は、もしも天下一品が太麺だったらづなるか!?を考えてみた。

 天下一品の高粘度なスープは、一般的な醤油ラーメンに対して2桁程度は粘度が高く、おそらく10の3乗センチポワズくらいだと思う。ということは、箸で持ち上げられた麺に絡んだ天下一品のスープは、さらさら低粘度な醤油ラーメンと比べて2桁程度も強く重力に逆らう抵抗力を受ける…ということになる。

 麺に絡んだスープが、重力に対抗するより強い力を受けるということは、つまり、重力に逆らいつつ高い場所まで持ち上げられてしまうということである。そして、もしも、麺からスープが落ちることがあれば、高い場所から落ちたスープ滴が大きな運動エネルギーをスープ液面に叩きつけるということであり、悲惨な飛散を生じさせること間違いない。この「高いところから汁が滴ることによる飛散」は、粘度が高い麺類が持つ宿命である。高粘度スープを誇る天下一品は、そんな運命を持つ。

 ところで、麺類から落ちる汁というものは、たいてい麺の先端から滴ると相場が決まっている。その理由は単純で、「表面積を最小にしたがる」スープの表面張力により、曲率が大きな箇所からしかスープは滴り落ちないからだ。そして「表面積を最小にしたがる」ということから、(体積と表面積で連立方程式を組めばわかるように)円筒形状に沿って吐出される液体は、円筒形状の半径をRとすると半径3/2 Rの球状になって滴り落ちることになる。つまり、麺に沿って(麺の端部から)滴り落ちるスープは、麺の太さに比例する大きさで下に落下していく…ということになる。つまり、粘度が高く・麺の径が太い食物は、「高い場所から・大きな液滴を落とすので、悲劇的な飛散を引き起こす」ということである。

 天下一品の場合は、スープの粘度は高いがその麺は細い。それはつまり(麺形状の効果はとりあえず無視すれば)天下一品ラーメンは、高いところからスープ液滴が落ちやすいけれど(麺の太さにしたがって)液滴径が小さいがゆえに、まだスープ飛散はマシなはず…ということになる。

 というわけで、天下一品がもしも太麺だったら、汁の粘度的にスープ液滴が飛散することよる汚れを気にしがちな女性には、人気が低いラーメン店になっていたに違いない。とはいえ、天下一品ラーメンの麺が細いからといって、女性人気が低くないかどうかは…よくわからないのだけれど…。

天下一品がもしも太麺だったら…(汁の粘度的に)女子人気が低かったに違いない!?天下一品がもしも太麺だったら…(汁の粘度的に)女子人気が低かったに違いない!?






2017-03-06[n年前へ]

父が書いた「はるか」な物語  share on Tumblr 

 『超巨大ブラックホールに迫る―「はるか」が創った3万㎞の瞳』が届いた。本のタイトルそのままでは内容が伝わりにくいような気がする電波天文観測衛星「はるか(MUSES-B)」に関する20年以上の物語…ひとことで言ってしまえば、父が書いた「はるか」な物語。

 客観的な目で読んだ人が、どんな感想を持つかは全くわからないけれど、手にとって何度もたくさん読まれたなら、少し嬉しい気がする。

 それにしても、父の名が付けられた小惑星が十年近く前から空に浮かんでいた…なんて知らなかった。

久(ひさし、10224 Hisashi)は小惑星帯に位置する小惑星。埼玉県のアマチュア天文家、佐藤直人が1997年に秩父市で発見した。JAXA宇宙教育センター長や電波天文衛星はるかのプロジェクトマネージャーなどを勤めた平林久にちなんで、2009年4月に命名された。

2017-03-05[n年前へ]

現実のリアルタイム風景と、そこから眺めた好きな時間・瞬間を合成してVR的に眺めてみよう!?  share on Tumblr 

 先日、周囲全方向を撮影することができるRicoh Theta Sを使い、24時間にわたり11段階の多段露出撮影画像からリトル・プラネット(とても小さな星を上空から撮影したような)風動画を作ってみました(Ricoh Theta S で24時間のHDR(多段露出)撮影をして遊んでみる!?)。けれど、そんな風に景色を離れたところから第三者的・客観的に眺めるのではなくて、その場に立って一人称的に景色を眺めたくなりました。そこで、合成した高画質4K動画をYoutubeに(360度映像だというタグを付けて)アップロードしてみました。

 こうすることで、スマホからYoutubeアプリケーションでアクセスし、VR用レンズセットを取り付けて眺めれば、あたかもこの場所に立ち・数百倍近く速く時間が流れる中で、夜空や太陽の影を眺めることができます。

 そして一番面白いのは、24時間の撮影を行った場所に立って、目の前にあるリアルタイムな実際の景色を眺めつつ、「東の空に昇る太陽や夜星や夕焼けや」…24時間の中にある美しい瞬間や一番好きな時間を、スマホに覗いて自由自在にVR合成しながら眺めてみると…とても不思議で面白い気持ちになってきます。

 今日は、24時間にわたる、周囲全ての4πステラジアンの全天周風景を、11段階多段露出のハイダイナミックレンジ撮影をして、その映像を4K映像に変換して眺めてみました。

現実のリアルタイム風景と、そこから眺めた好きな時間・瞬間を合成してVR的に眺めてみよう!?現実のリアルタイム風景と、そこから眺めた好きな時間・瞬間を合成してVR的に眺めてみよう!?






2017-02-26[n年前へ]

Ricoh Theta S で24時間のHDR(多段露出)撮影をして遊んでみる!?  share on Tumblr 

 Ricoh Theta Sを制御するPython 3.xコードを書いた (「Ricoh Theta S で2017年旧暦1月満月の夜を撮ってみる」)ので、Theta Sを載せた三脚を高く立て、24時間を少し超えるくらいの時間にわたり、11段階の露出時間での撮影を交互に続けてみました。ちなみに、撮影に使ったPython コードは下記になります。

import osc
import theta
import time
thetas = RicohThetaS()
thetas.setCaptureMode( 'image' )
thetas.setOption("exposureProgram", 1 )
thetas.setOption("ISO", "100")
thetas.setOption("whiteBalance", "daylight")
shutterSpeeds1 = [0.00015625, 0.0005,
    0.002,0.008,0.03333333,0.125,0.5,
    2,8,30,60]
for i in range(400):
    for shutterSpeed in shutterSpeeds1:
      thetas.setOption("shutterSpeed", shutterSpeed)  
      time.sleep(1)
      response = thetas.takePicture()
      thetas.waitForProcessing(response['id'])
      time.sleep(1)
      thetas.getLatestImage()
      time.sleep(1)
thetas.closeSession()

 こうして、 1/6400秒~60秒までの11段階にわたる露出時間で撮影した画像群を、下記のPythonコードでHDR(ハイダイナミックレンジ)合成します。

import cv2
import numpy as np
iniID = 11006 # fileName
for i in range(400):
    files=["hoge"+"R00"+str(iniID+j+i*11)+".JPG" for j in range(11)]
    imgs = [cv2.imread(file) for file in files]
    mertens = cv2.createMergeMertens()
    resImg = mertens.process(imgs)
    resImg = np.clip( resImg*255, 0, 255 ).astype('uint8') 
    cv2.imwrite("hoge"+
                "out_"+str(1000+i)+".jpg", resImg)
 そして、11段階の多段露出画像を合成した連番画像ファイルを動画ファイルとして結合することで、たとえば、下に貼り付けたようなLittle Planet風のタイムラプス(微速度)動画として眺めることができます。撮影を行ったのは、都会に近い薄曇りの空の下ですが…それでも恒星が浮かぶ宇宙空間を回転する地球が進んでいるさまが見えるような気がしてきます。

2017-02-12[n年前へ]

Ricoh Theta S で2017年旧暦1月満月の夜を撮ってみる  share on Tumblr 

 思い返せば2015年は忙しかった。長身の国オランダに入り浸ったり、大学病院に入院したり、タイのスコータイやチェンマイあるいはバンコクで Ricoh Theta S と自作治具を抱えて全天周HDR距離マップ付き動画に挑戦したり、人生で2回目のスカートを送風機でめくる実験をしたり…と七転八倒の毎日だった。

 そんな人生七転八倒のお友達 Ricoh Theta S ともっと戯れたい!というわけで、OpenSphericalCameraのTheta S 制御用 Python コードを3.x用に書き換えて、長時間露光の微速度撮影で満月の夜を撮影をしてみた。

 旧暦1月の満月の夜を、露光60秒で20分ほどの時間、微速度動画を撮ってみる。太陽のように明るい満月と、都会に近いけれどそれでも見えるいくつもの星 は、北極星を中心に廻っている。もしも、渋谷のスクランブル交差点や、上野公園の桜の下、あるいは、山手線のホームで眺めてみたら、一体どんな景色が見えてくるだろう。

Ricoh Theta S で2017年旧暦1月満月の夜を撮ってみる






2017-01-29[n年前へ]

「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみよう!?  share on Tumblr 

 かつて、スマホに搭載されているカメラのレンズはとても小さく、綺麗なボケとは無縁の存在でした。しかし、今や最新のスマホには特殊処理によるボケ生成機能などが備えられています。カメラレンズの光学開口径が小さくとも、たとえば2眼カメラなどを備えて距離情報を取得して、距離情報などからボケを人工的に合成するといった仕組みです。

 そんな最新スマホを持たずとも、大レンズのボケ味を手に入れるために、「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみました。スマホ動画から巨大開口レンズ撮影の手順はとても簡単、まずは目の前の風景にスマホを向けて・なるべくスマホが平面上を動くように意識しながら(スマホを動かしつつ)動画撮影します。そして、動画の各コマから画像ファイル群を生成し、それぞれの画像が撮影された位置や方向にもとづいて撮影された光情報を加算合成する、というものになります。

 細かい手順は、スマホ撮影動画(の展開画像をもとに) Bundler: Structure from Motion (SfM) から出力された刻々のカメラ位置・方向や特徴点情報ファイル(bundler.out)を読み込み、それらのカメラ情報にもとづいて、刻々の撮影画像をレンズ開口面に沿った(同じ方向を向く平行カメラが存在していた場合の)光線画像を位置・角度ズレを踏まえて重ねることで、任意のピント位置に焦点を合わせた超巨大開口レンズ撮影画像を生成する…というものです。

 試しに、iPhoneを約1.5m×1.0mの範囲で動かしつつ動画撮影し、つまり、レンズ直径約1.5mに相当する範囲で動かしつつ動画撮影し、その画像群から開口合成により超巨大カメラの撮影画像を作り出してみた結果が右上の画像です。

 右上画像を眺めてみても、良好なボケ味どころか、全くピントが合っていない画像にしか見えません。直径が1mを超える開口を持つカメラレンズとなると焦点深度もとても浅くなるのでピントがなかなか合わない…というわけでなく、手持ち撮影動画からのカメラ位置・方向精度が低いせいか、単一カメラに平行合成した後のズレが大きいようです。

 ちなみに、試しに各画像を(撮影方向による傾きを補正しつつ)位置毎に並べてみると、下の画像のようになります。動画撮影からのカメラ位置推定精度が果たして不十分なのかどうか、次は撮影カメラ位置を精度良く知る事ができる撮影治具でも作り、また再挑戦してみたいと思います。

 上記処理のコード手順、Python/OpenCVで書いたコード処理手順は、bundler.outからカメラ位置・方向・焦点距離や歪みパラメータを読み込み、cv2.initUndistortRectifyMapにカメラ情報を渡して、各撮影画像の向き補正用のホモグラフィーマップを作成してremapで変換した後に、各撮影画像を加算合成するという手順です。

 Bundlerの出力ファイルを読み込んでライトフィールド合成を行うOpenCV/Pythonコード、まだまだ間違い含まれているような気もしますが、とりあえずここに貼り付けておくことにします。

import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import math
%matplotlib inline

class camera:
    def __init__(self):
        self.f = 1.0
        self.k1 = 0.0
        self.k2 = 0.0
        self.R = [[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]
        self.T = [0.0,0.0,0.0]

def readBundlerOut( filePath ):
    f = open(filePath, 'r')
    list = f.readlines()
    f.close()

    numberOfCameras = int((list[1].split())[0]) 
    cameras = []
    for i in range(numberOfCameras):
        aCamera = camera()
        fk1k2 = [float(j) for j in list[5*i+2].split()]
        aCamera.f  = fk1k2[0]
        aCamera.k1 = fk1k2[1]
        aCamera.k2 = fk1k2[2]
        rot = []
        for j in range(1,4):
            rot.append( [float(k) for k in list[ 5*i+2+j ].split()] )
        aCamera.R = rot
        aCamera.T = [float(k) for k in list[ 5*i+2+4 ].split()]
        cameras.append(aCamera)
    return cameras

def readImageList( listPath, imageDirPath ):
    f = open(listPath, 'r')
    list = f.readlines()
    list = [ i.rstrip() for i in list ]
    f.close()
    list = [imageDirPath+fileName for fileName in list]
    return list

class lightField:
    
    def __init__(self):
        self.w = 2000
        self.h = 2000
    
    def loadImageListAndMakeLightField( self, 
                    imagePathList, cameraList, workList, scaleA ):
        self.cimg  = np.zeros((self.h, self.w,3), dtype=np.uint8)
        sum = 1.0
        for i in workList:
            img = cv2.imread( imagePathList[i], cv2.IMREAD_COLOR )
            h, w = img.shape[:2]
            imageHeight = img.shape[0]
            imageWidth =  img.shape[1]
            focalLength = cameraList[i].f
            principalPointX = 0.500000
            principalPointY = 0.500000
            distCoef = np.array([ 0.0, 0.0, 0.0, 0.0, 0.0 ])
            cameraMatrix = np.array([ 
                [focalLength,   
                 0.0,          
                 imageWidth  * principalPointX], 
                [0.0,           
                 focalLength,  
                 imageHeight * principalPointY], 
                [0.0,           0.0,          1.0] 
                           ])
            newCameraMatrix, roi = cv2.getOptimalNewCameraMatrix(
                cameraMatrix,
                distCoef,
                (img.shape[1], img.shape[0]),1,
                (img.shape[1], img.shape[0]) )
            rotMatrix = np.array( cameraList[i].R )
            map = cv2.initUndistortRectifyMap( 
                newCameraMatrix,
                distCoef,
                rotMatrix,
                newCameraMatrix, 
                (img.shape[1], img.shape[0]),
                cv2.CV_32FC1)
            
            undistortedAndRotatedImg = cv2.remap( img, 
                        map[0], map[1],
                        cv2.INTER_LINEAR )
            
            scale = 1.0
            pt3 = np.array(cameraList[i].T) - np.array(cameraList[0].T)
            x =  ( self.w/2.0 - pt3[0] * scale * scaleA ) 
            y =  ( self.h/2.0 - pt3[1] * scale * scaleA ) 
            pts1 = np.float32( [[0,      0],
                                [w, 0],
                                [w, h],
                                [0, h]])
            pts2 = np.float32(  [[x,           y],
                                 [x + w*scale, y],
                                 [x + w*scale, y + h*scale],
                                 [x,           y + h*scale]] )
            M = cv2.getPerspectiveTransform( pts1, pts2 )
            img2 = cv2.warpPerspective( 
                undistortedAndRotatedImg, M, (self.w, self.h) )
            sum = sum + 1.0
            self.cimg = cv2.addWeighted(
                 self.cimg, (sum-1) / sum, 
                 img2,      (1.0) / sum, 0)
    
    def showImage(self):
        plt.figure( figsize=(14,14) )
        plt.imshow( np.array(self.cimg2) ) 
        plt.autoscale( False )

「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみよう!?「手持ちスマホ撮影動画からの超巨大開口レンズ撮影」に挑戦してみよう!? 






2017-01-21[n年前へ]

「入金」を意味する「チャージ」の歴史 第1話  share on Tumblr 

 現代の日本では、「入金する」ことを「チャージ」と表すことが多い。たとえば、何かを買ったり・使ったりすることができる権利や口座など、あるいは、そういう用途のカードに再入金を行うことを「チャージ」と表現することが多いように思う。

 ところが、それを英語で表現しようとすると、それは「チャージ」ではない、というワナがある。「再入金する」ということを表すために、top-upとかadd valueとは言うけれど、chargeと言ってしまうと「課金する」「支払いを(さらに)求める」といった意味になってしまう。つまり、意味が逆になってしまう。

 この「意味の逆転」が生じるに至った歴史・主要因として、まず一番疑いたくなるのがJR東日本が2001年から提供している乗車カード・電子マネーサービスであるSuica(スイカ)だ。それまでに、再入金できないプリペードカードはすでに広まっていたが、Suica(スイカ)は、再入金可能かつ広まったプリペードカードの先駆けだった。

 その「Suica(スイカ)サービス開始」のプレスリリース、2001年9月4日にJR東日本が出したプレスリリースでは、カードに再入金をすることを「チャージ(ご入金)」と表現している。もっとも、この時代の日本では、入金=チャージという共通認識は確立されていなかったようで、「チャージ」には「チャージ:Suicaのイオカード部分に入金すること」という、注釈も付いている。今や「チャージ」という日本語に注釈が付くことは少ないが、この時代には注釈がまだ付いていた。ちなみに、イオカードというのは、SUICAカード以前に使われていた磁気式プリペイド乗車カード(に相当する機能)のことである。

 もうじき20年近く前になる21世紀の初頭の日本、JR東日本が「なぜ、再入金することを表すために、チャージという言葉を選んだ経緯・理由」をJR東日本に(もしその経緯などを示す資料などあれば?と)問い合わせてみた。そして、JR東日本から頂いた回答は次のようになる。

 明確な資料等はございませんが、Suicaにつきましては、従来の磁気式のイオカード等、使い切りの形ではなく、充電式の電池等のようにカードに再度入金をしていただくことで、1枚のカードを繰り返しご利用いただけることをお客さまにわかりやすくお伝えする趣旨で充電等を意味する「チャージ」の用語を用いております。なお、一部、わかりづらいというご意見がありましたので、宣伝物等のご案内については「入金(チャージ)」という表現を使用しております。

JR東日本

 CHARGEの語源は、ラテン語の「荷車(carrus)」から、「荷を積む(carricare)」という意味が、古フランス語を経て、英語で使われるようになったものだ。荷を積むことは、負荷を掛けることであって、それは支払いを求める(責任や仕事の分担を求める)ことにも繋がるし、充電された状態にするための「負荷」を掛けることも意味する。この車に積む「荷」をプラスの(足す)作用を持つ存在と捉えるかマイナスの(引く)ものと考えるかが、2017年の日本語のチャージと英語のChargeの違いに繋がっているように思われる。

 JR東日本が「チャージ」という言葉を選ぶに至った歴史の前ページ、そして、それ以外のエトセトラ…については、次にまたメモ書きしてみたいと思う。

2017-01-15[n年前へ]

データで眺める誕生日、生まれる人が少ないのは「土日祝日と○月×日」  share on Tumblr 

 データで眺める誕生日、生まれる人が少ないのは「土日祝日と○月×日」を書いた。人が生まれる誕生日時は、平均的に眺めてみれば、比較的精度良くコントロールされているものだ。

 データで眺めてみると、生まれる人が少ない「土日祝日と4月1日」と比べて、普通の平日は2割〜3割くらい生まれる人が多くなっています。誕生日はその年のカレンダーと連動しているので、誕生した人が多い日・少ない日は、年によって偏りが生まれます。ちなみに、休みとして月日がいつも決まっている祝日は、いつの年であっても「生まれた人は少ない」ということになるので、色々な年で平均してみてもやはり誕生日には偏りがあることになります。

2017-01-14[n年前へ]

ライトフィールドプリント最適化のためのBlenderシミュレーション その1  share on Tumblr 

 いくつもの視点から見た映像から視点変化に応じた見え方を再現するライトフィールド・プリント(インテグラル・フォトグラフィー)を作るために、Blender を使った透明シートへの印刷シミュレーションをしながら、効率的な印刷方法に挑戦してみた。

 どんな場合でも汎用的に使うことができる一般的な画像に対して、視点変化に応じた見え方を再現しようとすると、偏光素子を重ねるなど特殊な方法を使うのでなければ、視野を制限するマスク(アパーチャ)に相当する層を上にプリントした上で、視野変化に応じて見える光(色)をさらにその下にプリントすることになりそうだが、そうすると、次の問題が生じる。変角解像度を両立させるためにはマスク(アパーチャ)を小さくしたくなるが、そうすると画像が暗くなる。

 この問題に対して最適解を出そうとすると、マスクの口径(アパーチャー)が持つ周波数特性を、視点変化に対する見え方変化の周波数特性と一致させたくなる。つまり、もしも、視点が変化しても見え方の変化が小さい方向があれば、その方向に対してはマスクの口径(アパーチャー)を大きくし(周波数特性を鈍くし)、視点変化に対して見え方が敏感に変わる方向があれば、その方向に対しての口径を狭くしたくなる。つまり、高周波が鈍ることを防ぎたくなる。

 というわけで、ライトフィールドプリントの上面に配置したマスク(アパーチャ−)形状を、視点変化に対する見え方の変化(ライトフィールド勾配)に連動した方向性を持つ楕円形状にした画像生成をするPythonコードを書いてみた。そして、スタンフォードの The (New) Stanford Light Field Archiveをサンプル画像として使い、Blenderでライトフィールドプリントのシミュレーションをしてみたのが下の動画だ。

 眺めてみると、マスクサイズを固定とした範囲では、明度と変角解像度という相反する項目の両立が改善したような気もするが、空間方向変化(空間解像度)と連成した処理になっていないこともあり、まだまだ修正すべき項目が多い。…というわけで、次は、変角解像度と空間解像度の最適化を考えてみることにしよう。

2017-01-08[n年前へ]

ネット画像から有名人の個人情報(静脈パターン)を可視化してみよう!?  share on Tumblr 

 SNSなど投稿した「ピースマークなどの指写真」から指紋を推定する記事「指紋がネットで狙われている! 手の画像は悪用恐れ… 国立情報学研が新技術の実用化目指す」を読みました。写真の解像度が高ければ、指紋の抽出は確かにできそうです。もっとも、2017年時点の、よくある撮影解像度やアップロード画像解像度を考えると、指紋抽出はまだ困難な気がします。

 撮影の解像度だけを考えれば、皮膚内での波長毎の吸収・散乱特性の違いによる静脈可視化の方が楽かもしれません。掌を走る静脈は、その模様が人ごとに違うため、個人認証機器に多く使われたりします。そこで、各波長(RGB画像)の特性の違いを利用して、静脈推定をしてみることにしました。

 まずはネット上から掌が映った写真を探してみることにします。有名人の掌が映った写真はとても多く、観客に手を振る写真・演説中に両手の掌を開いて聴衆に見せている写真など、さまざまなパターンの画像が手に入ります。

 そして、静脈を可視化するために色の違いを利用するとなると、重要なことは「圧縮率が低い画像を探す」ということです。なぜかというと、人の視覚系は明度に対しては敏感ですが、色の違いに対しては解像力が低いため、多くの画像ファイルでは色情報が圧縮され低解像度になっているからです。

 圧縮率が低く・掌が映った有名人画像を探してみると、まず最初に見つかったのが綾瀬はるかさんの写真です(下左図)。この画像に「静脈部分を抽出する画像処理」を掛けてみると、皮膚下を走る静脈が浮かび上がってきます(下右図)。

 静脈模様を可視化する用途には、ネットにアップロードされている画像では圧縮率が問題になります。しかし、自分で撮影する画像なら、撮影さえすれば、圧縮が掛かっていない画像が手に入ります。…ということは、個人情報を狙われやすい有名人の人は、静脈模様を覆い隠す「静脈盗撮防止用のコンシーラー」などが必需品になるかもしれません。

2016-12-30[n年前へ]

「π r2(パイアール2乗)=面積」式は、ひいらぎ愛 さんの乳曲率に適用可能か?問題  share on Tumblr 

 「面積表示のタイトルがいいでしょ」というtweetに思わず目を引かれて、紹介文を眺めた途端に思わず笑ってしまいました。

「魅惑の巨大乳輪 ひいらぎ愛 π r2(パイアール2乗)=面積176cm2」巨大乳輪に特化した新シリーズです。第一弾は乳輪直径15cm、面積176cm2の…
そして、ふと考えたのです。
「乳というものは、多くの場合は立体的な存在である。少なくとも、ひいらぎ愛さんの場合は、超立体的なものに違いない。それなのに、面積計算を2次元平面上の公式を使って良いものだろうか?」
そこで、果たしてπ r2(パイアール2乗)=面積176cm2で良いのかどうか、軽く計算をしてみることにしました。

 ひいらぎ愛さんは、トップバストがバスト156cmでOカップということです。ということは、以前書いた おっぱい解析向けライブラリを使うと、彼女のトップバストに対してアンダーパストは45cm短い111cmであることがわかります。さらに、その乳を半球で近似した時の半径は30cmであると計算されます。

 乳を半球で近似すると、乳輪の面積は「半球を乳輪の大きさである立体角θで切り取った領域の表面積」となり、式で書くと、

 2π r^2 (1- Cos θ)
となります。立体角θは、「乳輪直径15cm」というのが、表面に沿って長さを計ったものだとすると、乳輪の立体角θは約29度です。すると、その乳輪の表面積は172平方cmとなります。π r2(パイアール2乗)から計算される177平方cmとは、約5平方cmほど違います。最初の2桁だけを比べれば、曲率を考慮してもしなくても全く同じ数値ですから、その差は十分小さいのかもしれません。

 「π r2(パイアール2乗)=面積」式は、ひいらぎ愛 さんの乳曲率に適用可能か?問題を解決するためには、その乳輪の直径だけでなく「円周の長さを計る」などの方法により乳表面の曲率を求める、という作戦が考えられます。それは、今後の課題としておこうかと思ます。