Ubuntu Weekly Recipe

第343回Ubuntuで天体写真を加工しよう

秋になり、夜空を撮影するのにも良い季節になってきましたね。今週のレシピでは、デジタルカメラでインターバル撮影した写真を加工して、タイムラプス動画やスタートレイル画像を作成する方法を紹介します。なお天体写真とタイトルにつけていますが、星空に限らず、雲、日没や日の出、街の人や車の流れ、船の往来、昆虫の羽化など、時間の経過とともに変化する、あらゆる写真に応用できます。

風の強い日に広角レンズで空を撮るだけでも面白い

インターバル撮影で素材を用意

まずは素材となる写真を用意しなくては話が始まりません。カメラを三脚などで固定し、インターバルタイマーを使って一定時間ごとにシャッターを切り続けましょう。インターバルタイマーとはその名の通り、設定した間隔ごとに、自動的にシャッターを切り続けることができる機能です。筆者はPENTAXのK-3という一眼レフカメラを使用していますが、このモデルは撮影間隔2秒間~24時間、繰り返し撮影回数2~2,000回の間で自由にタイマーを設定することができます。今回のサンプルは、すべてこのK-3で撮影しました。

本体内にインターバルタイマーを内蔵していない機種の場合、インターバルタイマー付きの外付けリモコンを使うという手もあります。リモコンが使えないコンパクトデジタルカメラなどの場合は、少々大変ですが、人力で一定時間ごとにシャッターボタンを押してください[1]⁠。

写真からタイムラプス動画を作成する

写真が撮影できたら、それをもとにタイムラプス動画を作成してみましょう。タイムラプス(微速度撮影)動画とは、一定の間隔を空けて撮影した写真をつなぎ合わせて作成された動画です。少ないコマをつなげるため、時間を圧縮して、長時間の動きを短時間で見せることができるのが特徴です。

動画の作成にはavconvコマンドを利用します[2]⁠。avconvコマンドはlibav-toolsパッケージに含まれています。もしもインストールされていない場合、このパッケージをインストールしてください。

avconvはその名の通りオーディオ/ビデオのコンバーターですが、連続したファイル名を持つ複数の画像を動画ファイルに変換する機能があります。一般的にデジタルカメラで撮影した写真は「DSCxxxxx.JPG」のようなファイル名になっており、⁠xxxxx」の部分にはそのカメラのショット数が入ることが多いでしょう。しかしavconvの仕様として、最初のフレームとなるファイルは0から4の間の番号ではじまり、続くフレームはすべて連番である必要があります。このため、変換に先立ってファイル名のリネームを行っておきましょう。ここではフォルダー内のファイルすべてを、0からはじまる4桁の連番にリネームしました。

libav-toolsのインストール
$ sudo apt-get install libav-tools
フォルダ内のJPGファイルを連番にリネーム
i=0
for n in *.JPG
do
  mv $n $(printf %04d $i).jpg
  i=$(expr $i + 1)
done

avconvコマンドの使用例は次の通りです。⁠-r」オプションでフレームレート[3]⁠、⁠-i」オプションでソースとなるファイル、⁠-b」オプションでビットレート、引数に出力先のファイル名を指定します。コンテナフォーマットはファイル名の拡張子から自動的に判断されます。

ソースとなるファイル名には「%d」「%0Nd」といった指定ができ、これで前述の連番ファイルを指定することができます。printfのフォーマットと同様に、⁠N」には0でパディングされている桁数を整数で指定します。

今回はソースとなる写真が99枚ありましたので、入力、出力ともにフレームレートは割り切れる値である9を指定しました。99枚の写真を9フレーム/秒として入力し、9フレーム/秒として出力するため、出力される動画は11秒になります。当然ですがフレームレートを大きくしたほうがなめらかな動画が得られます。

また入力と出力のフレームレートに異なる数値を指定した場合、入力フレームが過剰な場合は間引きされ、逆にフレームが不足する場合は自動的に入力フレームを重複させ、指定されたフレームレートに落とし込もうとします[4]⁠。

連番のjpgファイルからogvの動画ファイルを作成
$ avconv -r 9 -i "%04d.jpg" -r 9 -b 15000k ../sky.ogv
自宅の屋上から15秒置きに撮影した空の写真99枚を、9フレーム/(99枚/9フレーム=11秒)の動画にしてみた例)

写真からアニメーションgifを作成する

YouTubeにアップロードするような場合はogvで出力すれば用が足りますが、場合によってはアニメーションgif画像のほうが都合が良いかもしれません。ImageMagickに含まれるconvertコマンドを使えば、複数の写真からアニメーションgifを作ることができます。

convertコマンドの引数は、ソースとなる全画像ファイルと出力先となるファイルです。ソースとなる複数のファイルを表示する順番で指定し、最後に出力先を指定します。⁠-delay」オプションは、次のフレームを表示するまでのディレイを指定するオプションで、N/100秒のNの部分を整数で指定します。つまり「-delay 5」を指定すると、20フレーム/秒のアニメーションとなります。好みに合わせて調整してください。

なお最近のデジタルカメラは画素数の増大に伴い、非常に大きな画像を出力します[5]⁠。撮影したままの写真をそのまま加工すると、当然巨大なgifファイルが出来上がってしまいます。事前にconvertの「-resize」オプションを使うなどして、縮小した複製画像を作っておくと良いでしょう。また、撮影する段階でカメラの記録サイズ設定を変更し、小さいサイズで保存するのも有効です。リサイズの手間が省けますし、なによりSDカードの容量を圧迫しません。インターバル撮影では数百から数千枚の撮影を行うこともありますので、そもそも最大サイズで撮影すると、SDカードに収まり切らない場合もあるからです。

ImageMagickのインストール
$ sudo apt-get install imagemagick
フォルダー内の全JPGファイルを横800ピクセルにリサイズする例
for n in *.JPG
do
  convert -resize 800 $n resize-$n
done
jpg画像からアニメーションgifを作成
$ convert -delay 5 *.jpg ../sky.gif

作成したアニメーションgif画像はこちら(sky.gif)です。なお、sky.gifはファイルサイズが約11Mバイトありますので、ご注意ください。

スタートレイル画像を合成する

インターバル撮影した複数の画像を、一枚の画像に合成することもできます。gimp-startrail-compositorは、複数の画像からスタートレイル画像を合成するGIMPのプラグインです[6]⁠。筆者が先日、沖縄で撮影してきたこの写真を例に、スタートレイル画像を合成してみましょう[7]⁠。

星空の写真
星空の写真

まずダウンロードページから、最新版のzipファイルをダウンロードしてください。zipにはいくつかのファイルが含まれていますが、必要なのは「startrail.py」というPythonスクリプトだけです。これをホームディレクトリの「~/.gimp-2.8/plug-ins」以下にコピーしてください。

GIMPを起動したら、メニューの「ファイル⁠⁠→⁠画像の生成⁠⁠→⁠Python-Fu⁠⁠→⁠Startrail」を選択して、スクリプトを実行してください[8]⁠。以下のようなダイアログが表示されます。

python-fu-startrailダイアログ
python-fu-startrailダイアログ

「Light frames」には、合成するソースとなる画像が保存されているフォルダーを指定します。startrail.pyはこのフォルダー内にあるすべての画像ファイルを対象とするため、合成に使う画像以外のファイルは置かないでください。

「Dark frames」にはダークフレームが保存されているフォルダーを指定します。デジタルカメラで長時間撮影を行うと、写真にザラザラとしたノイズが乗ってきますが、このノイズだけを撮影した写真をダークフレームと呼びます[9]⁠。ノイズにはランダムに乗るノイズと、条件が同じなら同じように乗るパターンノイズが存在しますが、ダークフレームを使うことで規則的に表れるパターンノイズを減算、除去することができるのです[10]⁠。ダークフレームを撮影済みの場合は[11]⁠、⁠Use dark frame」「Yes」にしたうえで、ダークフレームが保存されているフォルダーを指定してください。ダークフレームを使用しない場合は「No」に変更してください。

「Save intermediate frames」「intermediate save directory」は、合成途中のフレームを保存するかどうかと、その保存場所を指定します。

「Live display update」「Yes」にすると、合成の過程がリアルタイムに表示されるようになります。

「Light frames」にソース画像のあるフォルダーを指定したら、⁠OK」をクリックしてください[12]⁠。

合成したスタートレイル画像
合成したスタートレイル画像

中間フレームの利用

gimp-startrail-compositorは、Light framesに指定された写真を、1枚ずつ重ねていきます。⁠Save intermediate frames」「Yes」にすると、この重ねている過程のフレームを「trailxxxxx.jpg(xxxxxは連番)」というファイルに書き出すことができます。たとえばこの中間フレームを前述のavconvで繋げれば、星の軌跡が伸びていくタイムラプス動画を作ることができます。

書き出した中間フレームをavconvで動画に変換した例

そのまま実行すると、このようにバラバラに光点が出てきてしまいます。startrail.pyでは、Light framesに指定されたフォルダーの中にあるファイルを、⁠os.listdir(frames)」というコードで読み込んでいます。しかしos.listdirがファイルを読み出す順番は不定なため、撮影された順番で処理が行われないのが原因です。最終的に一枚の合成画像を得たいだけであれば、合成の順序は関係ありません。しかし中間フレームで動画を作りたいような場合、これでは不都合です。そこで、あらかじめファイルリストをソートするようコードを変更します。

ファイルリストをソートするように変更
--- startrail.org   2013-02-22 05:53:51.000000000 +0900
+++ startrail.py    2014-09-15 18:09:04.000044516 +0900
@@ -146,7 +146,9 @@
    # Define an image to work in.
    # This will be created from the first light frame we process
    image = None
-   for file_name in os.listdir(frames):
+   files = os.listdir(frames)
+   files.sort()
+   for file_name in files:
        file_name = os.path.join(frames, file_name)
        if file_is_image(file_name):
            image_count += 1
ファイルをソートしてから処理した例

いかがでしょうか。様々なレンズが使用可能で、高解像度な静止画が撮影可能な一眼レフカメラを使えば、ビデオカメラのコマ落としとはまた違った動画を作ることができます。ちょっといいカメラをお持ちの方は、インターバル撮影で遊んでみるのもおもしろいでしょう。

おすすめ記事

記事・ニュース一覧