FOSS4G AdventCalendar 4日目です。
RICOH THETA
RICOH の THETA という360度カメラがあります。撮影した画像を THETA の閲覧用ソフトを使って開くと、ぐりぐり動かして遊ぶことができます。
THETA で撮影した、このぐりぐり動かせるデータはどのようなデータかというと、こんな横長の単なる画像です。
写真は Wikimedia Commons に CC BY 2.0 で公開されているものを使用させていただきました。
-
File:Photo from Ricoh Theta S after horizont correction (31850880602).jpg
- Artem Svetlov from Moscow, Russia, CC BY 2.0 https://creativecommons.org/licenses/by/2.0, via Wikimedia Commons
たとえば、このようにグリッド線を追加して、
THETA アプリで表示させるとこんなふうになります。
実は RICOH THETA の写真データは正距円筒図法で投影変換されて保存されており、 THETA アプリでは単なる画像を動的に投映変換しながら表示しています。
さあ! 再投影の時間だ!
元のデータが正距円筒図法ということがわかっていれば、他のプロジェクションに変換することも可能ですよね!
というわけで GDAL で再投影してみましょう。
下準備
まずは写真データを世界地図とみなして位置情報を付与します。横が $\left[ -180^\circ, 180^\circ \right]$ 、縦が $\left[ -90^\circ, 90^\circ \right]$ に相当することを、ワールドファイルで示してやればよいのです。ワールドファイルは非常に単純な形式なので手書きやスクリプトで生成してもいいのですが、今回は GDAL でワールドファイル付きの画像を生成し、いらない画像を削除することで入手します。
# もともと theta.jpg があるとする
$ gdal_translate -a_ullr -180 90 180 -90 -of JPEG -CO WORLDFILE=YES theta.jpg theta_.jpg
# 生成されたワールドファイル theta_.wld を theta.wld にリネームし、もとの画像に紐付ける
$ mv theta_.wld theta.wld
# いらないデータを削除
$ rm theta_.*
作成されたワールドファイルの中身はこんなやつです。
$ cat theta.wld
0.0669642857
0.0000000000
0.0000000000
-0.0669642857
-179.9665178571
89.9665178571
RICOH THETA S の場合、画像サイズは5,376 × 2,688なので、解像度は $res_x = \frac{360}{5376}, res_y = -\frac{180}{2688}$、左上ピクセルの中心位置は $\left( -180+\frac{res_x}{2}, 90+\frac{res_y}{2} \right)$ になります。
メルカトル図法
このデータを、まずはみんな大好きメルカトル図法に再投影してみます。
地球のように楕円体を考慮する必要はないので、単に +R=6378137
としています。別に統一されていればなんでもいいはずなので、 $\pi R$ がきれいになるように +R=572.9578
とかでもいいんですけどね。
表示する範囲を -te
で指定します(半径 R
の球とみなし、球表面を proj
の手法で平面投映したあとの紙面上の範囲)。今回は、生成する範囲は縦横ともに $[-\pi{}R, \pi{}R]$ とします。これは経度 $[-180^\circ, 180^\circ]$, 緯度 $[-85.051^\circ, 85.051^\circ]$ に相当します。
$ gdalwarp -s_srs "+proj=longlat +R=6378137" -t_srs "+proj=merc +R=6378137 +lat_0=0 +lon_0=0" -r cubic -te -20037508.34 -20037508.34 20037508.34 20037508.34 -ts 1000 1000 theta.jpg theta_merc.tif
広角レンズ(魚眼レンズ)の歪みはもちろんありますが、上下が圧縮されていない分、だいぶ自然な感じがしますね。更に地面部分や天頂部分を削除すると、全周パノラマ画像といった感じになるでしょう。
なお、 gdalwarp
の出力は JPEG 形式非対応なので、 GTiff で生成しています。
横メルカトル図法
メルカトルの次は横メルカトルです。基準経度は0度でやってみます。
$ gdalwarp -s_srs "+proj=longlat +R=6378137" -t_srs "+proj=tmerc +R=6378137 +lat_0=0 +lon_0=0" -r cubic -te -10000000 -10000000 10000000 10000000 -ts 1000 1000 theta.jpg theta_tmerc.tif
メルカトル図法は垂直方向はまっすぐ表現できていますが、横メルカトルだと水平方向がちゃんと表現されていますね。
大縮尺で詳細な地図では横メルカトル図法である、平面直角座標系や UTM が多く使われます。基準とする子午線から離れることによって、北の方位(真北)が地図上の北(方眼北)とは異なる方位となる性質を持つことは留意しておく必要があります。
正距方位図法
次に、自分が中心である全天モデルを考え、通常のカメラで撮影したときのことを考えてみます。
ある程度画角が狭い場合、ある点を中心とする方位図法を使うとよさそうです。そのなかでも、画角が2倍になればその画角で切り取られる円弧長も2倍になるような特徴を表現できる正距方位図法を使えばいい気がします。なんとなくですが。
とりあえず正距方位図法で再投影してみます。
中心点は $\left(0^\circ, 40^\circ\right)$ 、範囲は水平画角80度、垂直画角60度相当にしてみます。つまり正距方位図法の場合、水平範囲は $\left[-\frac{40}{180}\pi{}R, \frac{40}{180}\pi{}R\right]$ 、垂直範囲は $\left[-\frac{30}{180}\pi{}R, \frac{30}{180}\pi{}R\right]$ とすればよいです。
$ gdalwarp -s_srs "+proj=longlat +R=6378137" -t_srs "+proj=aeqd +R=6378137 +lat_0=40 +lon_0=0" -r cubic -te -4452779.61 -3339584.72 4452779.61 3339584.72 -ts 1200 900 theta.jpg theta_aeqd.tif
おー。いい感じに変換できていますね。
水平画角80度だと、35mmフィルム換算で焦点距離21mmくらいの広角レンズに相当します。
おわりに
RICOH THETA って周囲の状況をつかむのに適していますし、単純に結構おもしろくて楽しいんですが、いざ静止画として切り出すのに困るんですよね。
ということで、 GDAL を使った写真の再投影をしてみました。また、実用性はないかもしれませんが、他のプロジェクションを使うとおもしろい絵になるかもしれません。