はじめに
(追記12/19:Pixinsightのここフォーラムによると、現在このスクリプトはモノクロ画像専用で、ディベイヤーをしたカラー画像には使えないそうです。少し残念ですが、作者によると次回アップデートでチェック(?)するつもりだとのことです)
(追記12/20:ここのフォーラムの情報によると、次回のバージョン1.8.9-2で、カラー画像にも対応予定だそうです)
位置合わせをした画像をスタックする際、WBPPスクリプトやImageIntegrationプロセスの初期設定では"PSF Weight"が選択されています。これは画像に写っている星を測定して、シーイングや追尾精度、画像のSNなどを総合的に評価し、スタックの結果を最適化する重み付けのパラメータです。
この方法は優れていて、ガイドエラーなどによる品質の悪い画像も捨てることなく、一緒くたにPSF Weightでスタックしてしまった方が結果が良くなることもあります。これも以前話題にしました。
PSF Signalの値は、Image CalibrationやDebayer処理のときに計算され、画像のFITS Headerに埋め込まれます。基本はこの値でスタックが行われますが、ここで計算された値が必ずしも最適解ではないようなのです。
それで実は、最適解を求めるためのスクリプトが、昨年段階のアップデートで密かに追加されていたようでした。その名も”Weight Optimizer”スクリプトです。
このスクリプトでは、機械学習などで使われる勾配降下法によって、目的の量(画像のSNRやシグナル)を最適化するためのスタックのウエイトが計算されます。
まずは使い方
基本的な使い方
WeightOptimizerは、画像の位置合わせが終わったあと、スタックを行う直前に使用します。WBPPで処理を行っている場合は、すべての処理が終わった後、出力された”registered”フォルダの中に入っているファイルを Image Integrationプロセスに入力してください。そうしたら以下のように、三角マークをウインドウの外にドラッグ&ドロップして、”インスタンス”を作っておきます:
次にWeightOptimizerを起動します
Script>Utilities>WeightOptimizer
と辿ります。次のようなウインドウが開きます
まず(1)Use An ImageIntegration Icon をクリックして、先ほど作ったインスタンスを選択します。そうするとImageIntegrationに入力したファイルが読み込まれます。何を最適化するかはGlobal Optionsの(a)Objectivesから選べます。
4つの選択肢が用意されています。ここではPSF Signalを選んでおきましょう。一番下の"Formula"はより高度な使い方をするためのもので、SubframeSelectorが計算するキーワードを使って、最適化したい量を自由にカスタマイズできるようです。
Objectiveを選んだら、(2)の再生マークのようなボタンを押せば、最適化の計算がスタートします(かなり時間がかかるので注意してください)。最適化が終わると、下の図のように"Current Weights"に値が割り振られ、下のような画面になります
"solver iterations"には最適化の結果が出力されています。この結果の解釈は、次の節で述べることにします。
次は、(3)WRITE をクリックすると、ファイルのFITSヘッダーにウエイト値が書き込まれます。そしたらスクリプトを閉じ、先ほどのImageIntegrationに戻ってスタックを行います。
”Weights”を"FITS Keyword"とし、"Weight keyword"を"OPTWGHT"と指定することで、Weight Optimizerの結果を反映してスタックを行うことができます。
処理に時間がかかりすぎる時は"Subregion"を指定する
Weight Optimizerは、各ステップで複数回のスタックを実施してWeightの最適値を探すため、処理にやたら時間がかかります。その場合は、スタックする画像の一枚を開いて、Previewで画像の一部を選択した上で、”Grobal Options”の”Subregion"からプレビューを指定しておくと良いです。
これは便利な機能で、構図のなかで最も印象的な部分を指定してPSF Signalを最適化したり、最も淡い部分を指定してPSF SNRを最適化したりといった使い方もできそうです(後述)。
結果の吟味
グラフで比較
最適化の結果は、スクリプトの"Solver iterations"のグラフを見ると一目瞭然です。
赤いグラフはスタック後の画像のPSF Signalの値を各ステップごとにプロットした物で、ステップを重ねるにつれて値が改善しているのがわかります。ここで、ステップ0はすべての画像をウエイト1でスタックした結果、ステップ1がデフォルトのPSFSignalの値です。ステップ2での調整結果がステップ1よりも改善しているのが注目です。また青いグラフは最適化終了後の各フレームのウエイトを表しています。
ただし上記の結果には注意点があります。縦軸の値に注意すると最適化の結果は、
7.145 → 7.165
と僅か0.3%の改善に過ぎませんでした。これだとWeight Optimizerの有り無しを比較しても、相当なストレッチを行わないかぎりよくわからないかもしれません。
この辺りはまだ検証の必要なところです。上の例はフレーム数が10枚ですが、もっと枚数が増えるとパラメータの割り振りの自由度が増して、より良い結果が得られるかもしれません。しかしながらこのスクリプトは、画像のスタックを何回も繰り返して、最適なウエイトを探すので、枚数が多いと時間がかかります。処理時間も含めた本当の意味で「最適化」がどのあたりにあるのか? よければ読者の皆さんもご自身のデータで検証して、結果を教えてくれると嬉しいです。
スタック前のフレームに画質の差があると、効果あり
顧問が試した範囲では、スタックするフレームの画質差が開いている場合に、最適化の効果が大きかったです。
たとえばモノクロカメラによるLRGB合成で、L, R, G, Bの4枚の画像をさらにスタックした結果をL'とし、L’ RGB合成でSNを向上させたいという場合があります。
このとき、L画像に比べてR,G,Bの画像はフィルターで光をカットしている分画質が劣ります。したのグラフは、以前撮影したカモメ星雲の画像で、Weight Oprimizerを実行した結果です。
赤いグラフを見ていただけるとわかる通り、この場合はステップ1とステップ7の比較で11%ほどのPSF Signalの向上が得られました。
画像で比較
画像でも比較しておきましょう。左がL, R, G, Bの各フレームをPSF Signal Weightでスタックした結果、右がWeightOptimizerの出力したWeightでスタックした結果です。
うーん、微妙!PSF Signalの数値を信じる限りは、右の画質が良いはずですが、画像の見た目でどちらの画質が優れているかはみなさんの判断にお任せします。
おわりに:検証すべきことたくさん!
このスクリプト、Weightの微妙な調整で劇的な差が生じることは考えにくく、結果が地味なのは仕方なし。しかしながら、まだまだ検証すると楽しそうなことがたくさんあり、とても興味深いです。
今後の検証事項として、すぐに思いつく以下二つを挙げておきます:
- 【乱数指定による再探索】このような多変量解析での最適化問題では、最適化するパラメータがローカルミニマムに落ち込んでしまい、真の最適値に到達できないということがよく起こります。その場合は探索のパラメータや初期値を変えて再探索することになりますが、このスクリプトでもそれらを調整できるようになっています:
ここのパラメータを変えたり、あるいは右のRondomをクリックすることでWeightの初期値に乱数を振ることもできるようになっていて、乱数指定で何回も探索すれば偶発的に最適解が見つかるなんてこともあるのかもしれません。 - 【プレビューのROI指定による恣意的な最適化】上の方で書いた通り、このスクリプトではプレビューでROI(Region Of Interests)を指定することで、画像の特定部分のみをつかって最適化を行うことができます。例えば銀河の腕を指定してPSF Signalで最適化した結果をA、周辺の淡い部分を指定してPSF SNRで最適化した結果をBとして、AとBのいいとこ取りをして、望みの結果を得ることもできそうです。
WBPP2の登場で、そろそろ頭打ちかなと思っていた天体写真の前処理が、もう少しだけ前進しそうで楽しみが増えました。今後、もうすこし検証していきたいと思っております。