More Related Content
Similar to C89.360°映像システムをつくる (20)
More from Yoshimasa Kawano (18)
C89.360°映像システムをつくる
- 1. 360°映像システムをつくる
― レンズ Hack for Raspberry Pi Camera #2 ―
秘密結社オープンフォース 総統 河野 悦昌
openforce@project2108.com
This text is CC 0 ( Public Domain )
はじめに
Ricoh THETA や MASPRO SP36 な ど 、 360° 撮 影 の で き る 小 型 カ メ ラ が 人 気 で
す。OculusRift や Google Cardboard などを使っての 360°ビューも注目されており、コンテンツ
も期待されています。
そんな楽しい 360°映像システムを、Raspberry Pi を使って作ってみましょう。
前回までのあらすじ
2015 夏コミでは、「レンズ Hack for Raspberry Pi Camera」 を刊行し、そこでは以下のように
解説と実験をヤりました。
- 2. • USB 接続の WebCam は性能が
出ない
• Raspberry Pi のカメラモジュール
は優秀
• 高解像度の魚眼レンズを使ってい
ろいろ捗ろう
• Raspberry Pi は 1440x1440 のサイ
ズで 30fps 動画が撮影できる
• 魚眼レンズを使うにはレンズを交
換する方法とコンバージョンレン
ズを追加する方法がある
• レンズ交換の場合は M12 マウン
ト、CS マウントを使う
• 交換レンズは Xiongshi
(Xiangyang) Photoelectric
Technology Co. Ltd. の XS-6003
が成績が良い
• コンバージョンレンズはイザワオプトの IDF-3 が成績が良い
• 実際の画質、および円い画像を一般の写真のように投影変換する方法について
は、次回。
ということで、次回が今回です。
今回やること
前回好成績だった、Xiongshi
(Xiangyang) Photoelectric Technology
Co. Ltd. の XS-6003。
これを使って実際のシステムをつくって
いきます。
• カメラモジュールをつくる
• Raspberry Pi と組み合わせる
• 撮影する
• ストリームする
• 360°画像を平面投影画像に
展開する
• 360°映像を平面投影映像に
展開する
• 360°映像ストリームを平面投射ビュー
- 3. カメラモジュールをつくる
レンズスペック
• 焦点距離 1.05mm
• f=2.0
• FOVΦ3.2 で 240°
• M12x0.5 mount
• 3Megapixel 対応とあるけど本当かな。
• Raspberry Pi 用の 1/4CCD だとセンサ短辺で何とか 180°ぐらい撮れる感じです。
カメラボードとの組み合わせ
カメラモジュールに、レンズを組み合わせます。カメラモジュールは前回同様、 Arducam の
ものを使います。
コレに搭載されている CCD は純正カメラ
ボードと同じく OMNIVISION OV5647 で、これ
のスペックは以下の通りです。
• 1/4”サイズ
• 撮像エリアサイズ 3.7x2.7mm
• 2592×1944 ピクセル(5 メガピクセ
ル)
360°
180°以上
360°x240°中華レンズ
FOVΦ3.2
Raspberry Pi
カメラバス互換ボード
OV5647 CCD
3.7x2.7mm
M12マウンタ
Raspberry Pi
- 4. • ピクセルサイズ 1.4μm x 1.4μm
これに、円映像を投影するので、FOV2.7mm 以内。縦横 2.7mm の正方形のエリアに円画
像を結像し、それを 1440x1440 で取得します。OV5647 には5メガピクセルの画素があります
が、そのうち2メガピクセルを使用することになります。
Arducam のボードは ebay などで多々売られてますが、本当の Arducam ではなくパチモノか
もしれません。そういったものの中には M12 マウントがセットになっているものもありますが、
今回入手したものは樹脂製でレンズをねじ込むのにも力まかせでないといけないなどのアレ
なところがありました。なので別途メタル製の M12 マウントを改めて取り付け直しています。
誰でも入手しやすくする
この組み合わせで一般にも入手できるよ
うに、Amazon などで販売をしようと考えて
います。BlueberryCam という名前になる予
感。
¥10000 を切りたいところですが・・・イロ
イロ作って販売するときに、値付けは原価の
3倍という原則が Makers であります。それを
考えると、どうがんばっても¥10000 を超して
しまいます。
何とかまとめ買い付けをして¥12000 ぐらいにはしたいところですが・・・乞ご期待!!
シリンダに入れてみる
Arducam のカメラモジュールにはネジ
穴が開いているのでいろいろ取付がやり
やすくなっています。ネジ穴を使って直接
ネジ止めするのではなく、ちょっとしゃれ
た感じでハンドリングできるようにもして
みました。50Φ のアクリルパイプを切り、
その内部にスタッドとワッシャー、ビスでい
い感じに固定できます。カメラモジュール
の角が少し当たりますので、アクリルパイ
プの内径にあわせて削っています。アクリ
ルの端はカプトンテープを巻いて割れ防止にしています。
BlueberryCam
360° FishEye Lens for Raspberry Pi
- 5. Raspberry Pi と組み合わせる
自分で作ると何がイイの?
冒頭にも紹介したとおり、Ricoh THETA や MASPRO SP36 など、360°撮影のできる小型カ
メラが市販されています。
• メガピクセル解像度
• 2~3 万円台で手に入る
• カジュアルに使える
更に、最近は THETA の 4K モデルも投入されました。こういったものは、手軽に使えるので
すが実は立ち入ったことをやっていこうとするといろいろ不自由です。
• インターフェースが WiFi というのは・・・
• 自動運転したいね!!
• ストリームしたいね!!
• 組み込みしたい!!
• 電源コンフィグレーションを自由にしたい
• 内部に録画しながらストリーミング
• 外部制御で撮影したい
• 安定性を・・・!!
例えばドローンに組み込んで、映像を撮影しながらモバイル回線経由でコントロールした
いですよね。バッテリをモバイル回線と共用にして、インターネット経由で Web インターフェー
スでコントロールするには・・・?
こういったことを Raspberry Pi で実現してみましょう。
Raspberry Pi のスペックは CPU ARM Cortex-A7 900MHz 4 コア(Raspberry Pi 2 Model B)
ですから内部で VLC 動かして配信とかも何とかなりそうです。
標準 Linux なので簡単に開発でき、C/Python/Java/PHP などの開発環境も、Raspberry Pi
で動かすことができます。cron やネットワークや USB は普通の Linux と同じなので、センサ連
動撮影、時刻をみて撮影、撮影してツィート、認識エンジン、・・・などなども自由に設定できま
すね! それも、値段も安く!!
- 6. 要件!!
• フル HD 画質相当が必要
• 有線
• 安く!
• 内部に録画記録
• 外部にストリーミング
• 電源はいろいろ小型化!
• 安定した動作!!
つくってみた
360°カメラ+Raspberry Pi + リチウムイオン電池、およびそれの PoE による充電/給電シ
ステムの組み合わせ。リチウムイオン電池は 15 時間分。更にこれに 20W 級の太陽電池と組
み合わせることでコンセントレスでのほぼ常時稼動ができます。
これは、商用電源レスで自律的に監視や測定などの様々な動作を行えるようにするため
の、基本となるユニットとして構成しています。基本ユニットは Raspberry Pi を含む 10cm 角の
ユニット。リチウムイオン電池を使うためのあれやこれやのノウハウもあるのですが、そちらに
ついてはまたの機会に。
自律ノード
基本ユニット
リチウムイオン電池
2.5時間 x 6セル
360°
カメラ
- 8. 撮影する
静止画・動画撮影プログラムをつくる
以下のコマンドを実行すると、test.jpg が得られます。
raspistill -h 1440 -w 1440 -o test.jpg
問題ないようであれば、Web インターフェースで同様の操作ができるようにします。
適当な php ファイルで、あらかじめ$filename に日付などからファイル名を生成しておき、以
下の system 関数で撮影ができます。
system ( "raspistill -h 1440 -w 1440 -n -o ".$filename );
更に、ページ下部に以下のように記述しておくとファイル生成したらすぐにブラウザに表示
されます。
<a href="<?php echo $filename ?>">
<img src="<?php echo $filename ?>">
更に、apache2 は www-data ユーザで実行されますが、www-data ユーザにカメラへのアクセ
ス権を与えるために、/etc/rc,local ファイルに、末尾の exit 0 行の前に以下の行を追加しておき
ます。
chmod a+rw /dev/vchiq
動画についても、元々用意されている撮影コマンドは以下のようになっていて、
raspivid -h 1440 -w 1440 -t 10000 -o test.h264
これで問題なければ、別の php ファイルに以下のような記述を入れておきます。
system ( "raspivid -h 1440 -w 1440 -s --segment 1800000 --wrap 24 -o
".$filename.” > /dev/null & “);
ここではあらかじめ撮影時間を指定するのではなく、撮りっぱなしとしています。--segment
指定は 30 分毎にファイルを分割する、--wrap は最大 24 ファイルまで、すなわち 12 時間を最
大として撮影しています。
撮影を停止するには、別 php ファイルに以下を記述し、これを呼び出すことで STOP として
います。
system("pkill -f raspivid");
- 11. ストリーミングする
raspivid -o - -t 0 -hf -w 1440 -h 1440 -fps 25|cvlc -vvv
stream:///dev/stdin --sout
'#standard{access=http,mux=ts,dst=:8090}' :demux=h264 > /dev/null &
Raspberry Pi 側で上記のコマンドを実行しておきます。
ビューワは適当なデバイスをネットワークで通信できるようにしておいて、 VLC を起動し、
「メディア」-「ネットワークストリームを開く」で、ネットワーク URL として
http://<Raspberry Pi の IP アドレス>:8090
を指定して再生します。
かなり遅延があるので、再生環境によって 1440x1440 の解像度は落としたほうがいいかも
しれません。
なお、Android の場合はビューワとして VLC ではなく MX Player が使えました。
うまくいくようであれば、上記のコマンドを PHP の system 関数で実行するようにしておきま
す。
ストリーミングの場合も、停止するときは、kill するようにしています。
pkill -f raspivid
pkill -f vlc
php で停止するスクリプトを作るときは、下記のようにしておきます。
system("pkill -f raspivid");
system("pkill -f vlc");
360°画像を平面投影画像に展開する
先に、部分拡大写真を掲載しましたが、やっぱり天地はひっくり返らずに表示したいですよ
ね。丸くなっているのも直したいですよね。
- 12. それを実現するには Hugin を使います。Hugin は GPLv2 ライセンスの OSS なパノラマ処理
ソフトです。複数の写真をキャリブレーション、アライメント、ブレンドしてパノラマ写真を作りま
すが、かなりの精度で写真を自動認識して処理します。
多くの機能を持つ Hugin ですが、今回は 1 枚の Fish-Eye 画像を投影変換する用途に使い
ます。
マルチプラットフォームで Windows/OSX/Linux で使うことができます。Raspberry Pi 上でも
使用できますが、かなり処理が遅いため Hugin 処理は別 PC でするのが良さそうです。
Hugin の操作
起動して、「①画像の登録」を行います。
レンズタイプを「魚眼 Thoby」、水平画角を「170」として読み込みます。焦点距離が 11.944
となりますが、読み込んだ後で焦点距離を変更するのでも OK です。「移動/ドラッグ」タブを
選び、マウスで画像や天球を引っ張って図のように調整します。
「投影法」はメルカトルか、正距円筒が良いでしょう。
「切り抜き」で、左:0 上:0 右:3000 下:700 ぐらいにしておきます。
いい感じになってきたら「ファイル」-「保存」として、プロジェクトファイルを保存します。
その上で「Interface」-「Advanced」を選び、「スティッチャー」タブでファイル形式を「JPEG」に
- 13. して「スティッチを実行」とすると、以下のような画像が得られます。
自動処理する
Hagin はとても高性能なのですが、マウスでごにょごにょするのではなく自動化したいです
よね。Hagin をインストールすると、hugin_executor や nona というコマンドも使えるようになりま
す。それぞれ、次のようにして使います。
hugin_executor -s projectfile.pto
nona -o outputfile projectfile.pto inpuitfile
hugin_executor はプロジェクトファイルの内容でスティッチを実行します。nona はプロジェク
トファイルと同じ動作を inputfile に対して行います。
nona は outputfile が outputfile0000.tif という名前になり出力されます。TIFF 形式になるの
で JPG などにする場合は変換しないといけません。
projectfile.pto をテンプレートとして使う場合は nona を使うのが便利でしょうね。
360°映像を平面投影映像に展開する
動画→数千枚の Fish-Eye 静止画→Hugin→数千枚の展開静止画→動画
という流れで実現します。
動画を静止画に分解する
ffmpeg を使います。
ffmpeg -i infile.h264 -f image2 -qscale 1 -qmin 1 -qmax 1 frames/
%06d.jpg
このようにすると、 infile.h264 が 000001.jpg, 000002.jpg, 000003.jpg … として分解さ
れ、frames ディレクトリ内に格納されます。
Fish-Eye 静止画を投影変換する
先のように、nona を使います。
nona -o temp projectfile.pto frames/000001.jpg
- 14. これで、最初のコマが投影変換され、temp0000.tif というファイルになります。
mv temp0000.tif changed/000001.jpg.tiff
これを名前を付けて changed というフォルダに蓄積していきます。
この処理を、jpg ファイル全部に対してすることになります。
投影変換した画像を動画に変換する
ffmpeg -f image2 -i changed/00%04d.jpg.tiff -r 24 -an -vcodec libx264
-pix_fmt yuv420p output.mp4
この処理で、changed に蓄積されたファイルを連番で動画につなげます。
python3 プログラムを作成する
以上の処理がうまくいくようであれば、python3 のプログラムとしてまとめます。
#!/usr/bin/env python3
# coding: UTF-8
import os
import os.path
import sys
import time
import re
argvs=sys.argv
filebodyname,fileextname = os.path.splitext(argvs[1])
# filebodyname=re.sub(r".[hH]264$","",argvs[1])
os.system('mkdir frames')
os.system('mkdir changed')
os.system('rm -rf frames/*')
os.system('rm -rf changed/*')
os.system('ffmpeg -i ''+argvs[1]+'' -f image2 -qscale 1 -qmin 1
-qmax 1 frames/%06d.jpg')os.system('ffmpeg -i ''+argvs[1]+'' -f
image2 -qscale 1 -qmin 1 -qmax 1 frames/%06d.jpg')
files = os.listdir('frames')
for file in files:
print(file)
os.system('nona -o temp projectfile.pto frames/'+file)
print("mv ok")
os.system('mv temp0000.tif changed/'+file+'.tiff')
print("mv ok")
os.system('ffmpeg -f image2 -i changed/00%04d.jpg.tiff -r 24 -an
-vcodec libx264 -pix_fmt yuv420p ''+filebodyname+'.panorama.mp4'')
- 15. 360°映像ストリームを平面投射ビュー
ここまでは、撮影→保存→後処理でパノラマ展開してきました。ただ Hugin を使うとやっぱ
り遅いです。PC を使って1枚1秒強かかります。1 分の映像を処理するのに 30 分以上かかるこ
とになります。
これを、リアルタイムでストレッチしたいな。
やりたいこと
• Fish-Eye → 展開
• 拡縮
• 向きをインタラクティブに
これは、現在開発中です。今のところ、以下のようなアプローチで進めています。
Unity を使う
RICOH THETA などの動画をオンデマンドで投影変換してビューする方法が以下のように
開発されています。
「Unity と Oculus で 360 度パノラマ全天周動画を見る方法【無料編】」
https://github.com/makoto-unity/PanoramaVideoWithUnity
ファイル動画はこれでできますが、ストリーミングは?
Unity でストリーミング
WebCam ならできるらしいです。ネットワークカメラを WebCam として騙してしまえば何とか
なるのではないか? Unity で WebCam を貼り付け、ビューする PC でストリーミングを仮想
WebCam として使えるデバイスドライバをインストールすれば・・・→目下試し中です。
HTML5 ベース
WebGL で動くもので three.js の examples
http://threejs.org/examples/
の中に、
video / panorama / equirectangular が WebM 動画ファイルを投影変換しています。現在
Raspberry Pi からは H.264 でストリーム出力していますが、WebM ストリームなら取れる・・・は
ず?
俺たちの戦いはこれからだ!