画像処理ソフト開発ごっこ

紫金山アトラス彗星のタイムラプス動画を作って遊ぶ

紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17110252.jpg

★固定撮影だけど、メトカーフガイドしたみたいな動画を作りたい
期待以上に明るい姿を見せてくれた紫金山アトラス彗星ですが、幸運なことに10月13日(日)と10月14日(月)の2日間にわたり、素晴らしい姿を堪能することができました。また、固定撮影ではありますが、なかなか楽しい写真を撮ることもできました。


さて、上記の撮影記の中でもいくつかタイムラプス動画を上げたのですが、今回は作りかけだった「固定撮影した画像を処理して、まるでメトカーフガイドしたみたいなタイムラプス動画を吐く」簡易プログラムを完成させることにしました。

<方針>
①画像処理の下ごしらえには、ニコン純正の無料アプリ「NXstudio」のみ使い、本格的なソフトは封印する。
②現像後の画像を動画に変換する部分はMATLABhomeの基本関数のみ使い、オプションの高機能ツール群は封印する。
③しばらく経つとコードを書いた自分自信が(なにをやったのか)忘れてしまうので、内容をまとめた備忘録を書く。

まあ、アレです。プログラミングのど素人が自分なりに知恵を絞ってちゃんと動くようにしよう、という気楽な遊びです。


★第1段階「RAW現像」
今回は、ニコンのデジタル一眼レフD810Aで撮影したRAW画像(NEFファイル)を素材にするため、RAW現像などの下処理は全てニコン純正の無料アプリ「NXstudio」のみで行いました。シルキーピクスと似た操作系を持ちますが、純正だけにニコンのカメラの各種機能を活かしやすくて大好きなアプリです。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17272801.jpg
<現像パラメータの設定>
撮影するときには、できるだけ『余計なこと』をされないように、ピクチャースタイルは「フラット」・ホワイトバランスは「晴天」・各種ノイズリダクションは「全てOFF」を選んで14bitRAWで記録しました。さすがにそのままでは鑑賞したときに寂しいので、味付けをしていきましょう

まずは、下記のように基本的なパラメータを弄り、彗星が『映える』ように調整します。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17322009.jpg
実際の画像を見てみると、「ホットピクセル」「輝度ノイズ」ともに軽微で、「カラーノイズ」のみ目立ったので、下記の設定でノイズを軽減させました。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17335950.jpg
次に、倍率色収差と周辺減光補正をするのですが、実質どちらも不要な印象でした。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17360449.jpg
さて、これで『撮って出し』の彗星画像を『映える』写りにお化粧できました。
今回やるのは科学写真ではありませんので、厚化粧でもオーライです(笑)
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17493674.jpg
※左:無調整現像 右:調整後

<RAW現像のバッチ処理>
1コマだけ弄ってRAW現像のパラメータが決まったら、これを残りの画像全てに適用させます。私の場合は下記のような手順でバッチ処理しています。

まず調整済みの画像を選択して、メニューから「調整」→「全ての調整をコピー」を実行して、各種パラメータを覚えさせます。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17530908.jpg
次に、処理対象となる画像全てを選択します。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17542458.jpg
 対象画像が選択されている状態で、メニューから「調整」→「調整を貼り付け」を実行すると、全てのRAW画像に同じ処理が施されます。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_17582759.jpg
<TIFFファイルで書き出し>
各種パラメータを調整済みのRAWファイルですが、今回はTIFFファイルで書き出すことにしました。

まず、対象画像を選択します。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18001422.jpg
次に、画像が全て選択された状態でメニューから「ファイル」→「書き出す」を実行すると設定窓が開きます。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18133669.jpg
今回は、16bitTIFF画像を自前のプログラムで処理して4k相当のmp4動画に加工するのが目的ですので、下記のような設定で出力を行いました。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18022468.jpg
これで、前処理は完了です♪


★第2段階「彗星にアライメント」
さて、今回の『難所』は、前処理した画像を「いかにして彗星核付近をロックオンして位置合わせするか」です。
もちろん既存のソフトを色々と組み合わせると可能だと思うのですが、それでは面白くないので、MATLABを用いて自前のコードを開発ごっこすることにしました。とはいえ、その基本ロジックは星雲処理用のコンポジットルーチンとしてすでに実装した経験があったので、今回はそれを「彗星向け」にアレンジする作業となります。
(実は、対彗星用のアライメントルーチンもZTF彗星の撮影時に仮実装していたものの、色々と不具合が多かったので、全面改修しました。)

※以下、画像の右半分が実際に書いたMATLABのコードで、左側が「何をやっているのか」の概念図です。ただし、似たことをやってみたい方への解説ではなく、あくまでも「自分が忘れないようにするための備忘録」程度の適当な物である点はご容赦ください。


<TIFF画像のロードと基準設定>
まずは、RAW現像して書き出したTIFF画像群を読み込む部分のコードを書きます。
ここでは、D810Aが記録した画像ファイル名中の「連番部分」を利用して読み込む対象や読み込む順序を決めるようにしてみました。 
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18334338.jpg
次に、アライメント(彗星核に位置合わせ)に用いる下ごしらえをするコードを書きます。
彗星は周囲の恒星や景色とは別な動きをしますので、位置合わせ(一種の画像マッチング)で評価するエリアを彗星の頭近傍に絞り込む必要があります。また、高速位置合わせを実現するために実装した「グリッドサーチ法」(本来は、地表に降り注ぐ高エネルギー宇宙線二次粒子群のコアをサーチするために編み出された一種の連続関数フィッティング法です。)の初期設定値を与えるのもこの部分です。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18355592.jpg
位置合わせする画像にはモノクロ変換した画像を用いました。RGBに分解してそれぞれ位置合わせする方法も考えたのですが、今回のケースではあまりメリットが無かったので、楽さ優先で書きました。
さて、白状すると(プログラミングの素人ゆえに)この箇所で苦戦しました。TIFFは16bitの整数型で輝度を記録しているのに対して、MATLAB内部の変数では最大値を1とする倍精度小数型で扱っているので、この型変換をちゃんとやっておかないと画像が破綻します。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18363575.jpg
次に位置合わせの評価エリアをトリミングして切り出します。
今回は、1コマ目のファイルから切り出した画像を位置の基準として固定的に用い、他のコマの画像は全てこれに合わせて上下左右にシフトして最適な位置をサーチする設計にしました。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_22393153.jpg
本来、基準画像はアンカーとして機能するのでそれ自身がシフトすることは無いのですが、今回は任意のコマの位置合わせが終わると次のコマの位置合わせ基準役に置き換わる仕組みにしているため、1コマ目の画像も同様の処理をしておきます。※単に配列名を共通使用する目的のためです。

基準画像用に対して最大シフト量分の余白を持たせた配列を用意し、基準画像をその中央に配置することで画像シフト用のマージンを確保します。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_22395181.jpg
カラー画像である本体も下記のように周囲にマージンを設けます。こちらは3層の3次元配列になります。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_22471550.jpg
また、最終的にはこの基準画像コマが動画の1フレーム目となるため、最終出力サイズ(今回なら4k)に合わせてトリミングしてTIFF出力しておきます。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_22500043.jpg



<全画像のアライメント処理>
次に、2コマ目以降の画像を順次読み込み基準画像と演算させることで、適切なシフト量を求めるアライメント処理について書きます。なお、アライメント対象画像についても、位置合わせの評価はモノクロ画像で行い、その結果を元のカラー画像に適用する方針で進めます。
※ここからFORループを回します。

紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_20392467.jpg
さて、難しかったのはこの部分で、N番目の画像を位置決めする際の初期値をどうするかで悩みました(ここを適切にしないと彗星をロストします)。この場合N-1番目の画像は適切にアライメントが済んだ状態なので、N番目の画像についてはN-1番目の最終シフト量を初期値としてシフトを開始するイメージで設計してみました。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18405432.jpg
このシフト量を元にして対象画像の中から適切な評価エリアを切り出します。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18411037.jpg
次に、対象画像全体をシフトしても破綻しないように、画像の周囲にマージンを設けます。下記の黄色の内部で画像が上下左右にシフトできるイメージです。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18412416.jpg
上記は位置合わせ評価用のモノクロ画像の場合ですが、カラー画像である本体も下記のように周囲にマージンを設けます。こちらは3層の3次元配列になります。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18413980.jpg
次に、対象画像の評価エリアを自由に移動できるように施します。イメージとしては四角い窓が開いた板を写真の前に重ねて、この板を上下左右にシフトできるようにする感じです。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18420432.jpg
さて、いよいよ今回のキモである「グリッドサーチ法」の準備に取りかかります。
グリッドサーチ法では画像全面を調査せず、「3×3のグリッドを標本として誤差評価し、その中から最善のグリッドを求めた後、グリッド幅を1/2に狭めてサーチを続行して、精度を上げるという行程を所定の精度になるまで繰り返す」仕掛けになっています。これにより、通常の(総当たり的な)画像マッチング法と比較して極めて高速に演算が終わることが期待できます。※ここでは、大きなグリッドから小さなグリッドに移行することを『次の深度に潜る』と表現しています。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18421903.jpg
さて、グリッドサーチにおける誤差評価基準は色々と考えられるのですが、今回は特に「対・彗星用」として、彗星頭部近傍の ①「評価エリア全体の輝度差の絶対値」と ②「評価エリア全体の輝度平均値」の両方を切り替えられる仕掛けにしました。
ちなみに経験上、「彗星核が不明瞭・コマ付近の輝度勾配が緩やか・彗星近傍に雲や障害物が無い」などのケースでは①が、「彗星核が明瞭・コマ近傍の輝度勾配が急・彗星の周囲に雲や障害物あり」などのケースでは②が好成績を収めています。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18424345.jpg
9点のグリッド中の最適位置が求まると画像をその位置にシフトして、次のサーチ深度に潜ります。これを所定の回数繰り返すことで、徐々に精度を上げていきます。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18425561.jpg
全てのサーチ深度が完了したら、元画像全体を最適位置にシフトした後に余白を切り取ります。
最後に、適切に型変換してTIFFファイルとして書き出すと、アライメント作業完了です♪
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18430724.jpg

★第3段階「動画に変換する」
お疲れ様でした。ここからが「お楽しみ」です。
彗星位置でアライメントしたTIFF画像を全て読み込み、AVI動画とMP4動画の両方を吐き出すコードをMATLABで書いてみましょう。実は、この辺りの操作についてはMATLABの標準装備関数が非常に優秀(FITSでもTIFFでもJPEGでもAVIでもMP4でも自在に扱える)なので、特に工夫する点はありません。

<TIFF→AVIの変換>
まずは、TIFF画像をロードしてAVI動画として出力するコードを書いてみます。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18484543.jpg
はい、これで終わり。
楽勝ですね♪


<AVI→MP4の変換>
次に、上記のコードで書き出したAVI動画をSNSにアップしやすいようにMP4に変換するコードを書いてみます。
紫金山アトラス彗星のタイムラプス動画を作って遊ぶ_f0346040_18500357.jpg
はい、完成♪
こちらも、工夫する要素はほとんどありませんので、楽ちんですね。

★77コマの画像を動画にしてみる
さて、目論見通り、うまくタイムラプス動画になったか見てみましょう。

ででん!!

やったー!大成功♪
プロトタイプでは色々と不具合があったのですが、今回の作業でほぼ解消したようです。
それになにより、今までは自作プログラムについて「メモすら残さずソースファイル中のコメント文のみしか情報が無い」という悲惨な状況だったのですが、今回のブログ執筆で、自分自身の頭の中がかなり整理されました。これで、何をやっていたのか忘れてもこの記事を見直せばOK。

・・・というわけで、誰得でもなく、あぷらなーと自身のための備忘録記事でした~(笑)


★★★お約束★★★
①あぷらなーとはプログラミングの素人です。ロジックやコードには誤りが含まれているかもしれません。
②特に文献などで勉強することもせず、あえて自力で悩む過程を楽しむ道楽としてプログラミングごっこしていますので、お詳しい方は、どうか厳しい突っ込みをなさらず生暖かく見守ってください。
③「グリッドサーチ法」は、高エネルギー宇宙線物理学の分野で「シンチレータで観測された到達二次粒子のデンシティ分布とNKG関数をフィッティングすることにより空気シャワー現象のコアポジション(大気が無ければ一次粒子が地表のどこに落下したか)とサイズ(大気に入射する寸前に一次粒子が持っていたエネルギーみたいなもの)の推定のため伝統的に用いられていた便法」の転用です。参考文献は見当たらないので、自分の修士論文を読みました(笑)
④対星雲用のバージョンではありますが「グリッドサーチ法」のイメージは過去記事↓が分かりやすいかもしれません。

※R6.11月4日追記
図面に誤りがあったため一部を差し替えました。
※R6.11月10日追記
意図通り動作しているかを最終チェックするためのコードを実装したので、その結果を基に「なにが起こっているのか」が視覚的に楽しめる動画を作ってみました。ブログサイトの制約でYoutube動画は1記事あたり1本しか貼り付けられないので、Xの記事中に動画を載せて埋め込んでみました。



名前
URL
削除用パスワード
by supernova1987a | 2024-11-03 20:18 | 画像処理ソフト開発ごっこ | Comments(0)

あぷらなーとの写真ブログ


by あぷらなーと
PVアクセスランキング にほんブログ村