スタック処理ソフトを自作した話

4月から5月にかけて、スタック処理ソフトを自分で作ってみようと思い立ち、Webの情報を集めながら何とか動くものを作ってみました。今回はこのソフトについて紹介したいと思います。

作成の経緯

以前、Deep Sky Stacker(DSS)を改造した記事を掲載しました。実は、この改造の途中で一旦挫折して中断したことがあります。

r77-maabow.hatenablog.com

この記事に書いた様に、「デッドピクセルマップによるホットピクセル/コールドピクセルの除去(以降デッドピクセル除去と記載)」が改造の1つの目的でした。改造に当たっては、DSSの処理の中身を理解しておく必要があります。しかし改造を始めた頃は、DSSのソースを見てもソースが複雑で(自分の理解度が悪くて)、かなり時間をかけても中身が理解できませんでした。日本語化など幾つか簡単な改造までは出来たのですが、それ以上はあまりに時間がかかるので一旦諦めて、その代わりに「デッドピクセル除去を行ったFitsファイルを作成するだけ(あとはDSS処理させる)」というソフト作ってお茶を濁していました。

とりあえず作成したソフト

このソフトを作る際に、画像処理ライブラリとしてOpenCVを使いました。以前からOpenCVは多くの画像処理を備えていることは知っていたので、OpenCVの機能を使えば自分でスタッキングする処理まで作れるのではないか?と考える様になりました。
また、今までDSSではうまくスタックできない場合もあるので、DSSとは異なるアルゴリズムを使えばそういう場合もスタックできる様になるのではという期待もありました。Google先生に「OpenCV 位置合わせ」で調べてもらうと多くの情報が出てくるので、「これはいける!」と思い、上記のソフト大幅に拡張し、スタックまでできる様にしてみました。

作成の目的

ソフトを作成するにあたり、目的を以下としました。

  • デッドピクセル除去~スタックまでを1つのソフトで実現する
  • DSSと異なるアルゴリズムを使い、DSSでスタックできない画像もスタック可能にする

作成したソフト

ソフトはMicrosoft VisualStudio 2019のフリー版を使いC/C++で作成しました。またGUIを作ると大変なのでCLIで作りました。作成したソフトのイメージを以下に示します。

コンソール画面

結果表示画面(OpenCVが持つ機能を使用)

スタック処理の概要

ソフトの細かい内容は省いて、肝となる位置合わせの処理をメインに記載します。

位置合わせは、特徴量パターンマッチング(画像中の特徴的な部分(特徴量)を計算して、2つの画像に同じものがあるかを判別する)という機能を使いました。2つの画像の特徴点を対応(マッチング)させ、それを元に画像の回転/拡大縮小/平行移動の量(アフィン変換行列)を推定、一方の画像を推定した量だけ変形させることで位置合わせができます。
特徴量を算出するアルゴリズムは色々あるそうですが、OpenCVではSIFT,SURF,ORB, KAZE,AKAZEというアルゴが使えるらしく、私はAKAZEというものを使いました。Gooble先生に探してもらったWebサイトなどを見ると、回転や拡大縮小、画像ボケや明るさなどが違う場合にも強く、計算時間も短縮されているということです。特に、この時はAZ-GTiしか持っておらず経緯台で使っていたので、回転に強いというのは重要でした。

処理の流れとしては、

  • 特徴点を抽出して特徴量を計算
  • 特徴点のマッチング
  • ポイント同士の特徴量の差が大きいものは除外(マッチング精度UP)
  • マッチングした特徴点のペアーの座標値から、アフィン変換行列を推定
  • その行列を用いてアフィン変換

となります。

以下はM42の画像で、特徴量抽出マッチング(マッチング精度UPまで)を行った画像です。

2つのフレームに対し特徴量抽出とマッチングを行った結果
対応する特徴点が線で結ばれている)

特徴点には基本的に星が抽出されていて、一部星がない星雲の明るい部分(白く飛んでいるところ)も抽出されているみたいです。マッチングが間違って線で結ばれているものも一部ありますが、ほぼ正しいマッチングができています。
上記5つの処理のうち4つめまでの処理はOpenCVに関数が用意されていて、残りの処理も簡単な処理なので、位置合わせの処理はWeb上のサンプルソースを見ながら比較的簡単に作ることができました。

位置合わせができればあとは加算平均をとるだけです。OpenCVでは画像を配列として扱い、配列同士を足し算するコード(A=A+Bなど)を書けば画像同士の加算処理が行われます。スタック枚数分画像を加算し、あとは枚数で割り算(A=A/n)すれば加算平均完了となります。

もちろん、スタック処理の前に、デッドピクセル除去や、ダーク、フラットが設定されていればその処理を行うように作成しました。併せて、スタック後の画像をオートストレッチする機能も追加しました。オートストレッチの処理はSiriLのソースとPixInsightのライブラリ(PCL)のソースを参考にしました。

スタック処理の結果

過去に撮影した画像をいくつかスタックしましたが、どうやら上手くスタックできるものと出来ないものがある様です。

以下は上手くいった例で、特に問題なくスタックできています。DSSで同じ計算をさせた結果と比べても特に遜色はありません。

左:16s×31を本ソフトでスタック&オートストレッチした画像
右:画像の一部を拡大したもの、上がDSSで下が本ソフト

一方、以下のような画像はうまくいきませんでした。

左:DSSでスタックしたもの、右:本ソフトでスタックしたもの

アルゴリズムを理解していないので想像ですが、周りに星雲などがなく単に暗いだけという星が多いと、その星が特徴点として抽出されても特徴(星の周囲の強度分布??)が皆同じ状態(暗いだけ)なので、マッチングがうまくいかない(どの星ともマッチしてしまう)ことが要因ではないかと考えています。
DSSで同じ画像をスタックすると、弾かれるフレームは多いのですがスタックは行われます。この画像は星像が肥大しているので、DSSではこのように星像が大きいと星としては検出されないみたいです。また、星の数自体も少ないため、位置合わせができなくて弾かれてしまっています。

DSSと別のアルゴリズム(特徴点マッチング)だと上手くいくのではないか? と思ってスタックソフトを自作してみたのですが、残念ながら目論見は外れてしまいました。

モザイク合成処理の追加

上記の様に、うまくスタックできない画像があることが分かり残念でしたが、特徴点マッチングを使っているので対象画像はDSOである必要はありません。それで試しに月の画像をスタックしてみたところ、ちゃんと位置合わせができました。
今まで月のモザイク合成はGIMPを使って手動で行っていました。フリーのHuginというソフトも使ってみましたが、風景写真をターゲットにしている様で月のモザイクの様に超長焦点の場合ちょっと使い勝手がよろしくありません。MicrosoftのICEというソフトもよく使われていますが、2020頃から非公開になっている様です(Internet Archiveからダウンロードは可能)。私の場合4枚程度のモザイク合成なので、まぁ手作業でいいか.. と思っていましたが、このソフトを少し拡張してモザイク合成ができるのであれば、機能追加しない手はありません。

そこで、スタッキング機能の位置合わせまでの処理をそのまま流用し、最後の加算平均の部分をモザイク合成処理に書き換えたものを作成しました。処理は、画像の重複部分に対し、双方の画像に(境界にグラデーションを付けた)マスクをかけて加算合成するというものです。明比較合成でなく加算にしたのは、ディストーションなどで位置が完全に合ってない部分があるので、明比較合成にするとその部分がボケてしまうためです。

ちょっと分り難いですが、以下はマスクして加算するイメージ図です。

モザイク合成処理のイメージ:画像の重複部分にマスクを掛けて足し算

4分割の月の画像でテストしたところ上手くいったので、これで完成と思っていました。

ところが、随分前に撮った9数分割した月の画像でテストしたところ上手くいきません。4枚の合成だと、全ての画像に重複部分があるのでこの処理でも問題なくモザイク合成できましたが、もっと細かく分割されたのもだと全ての画像に共通の重複部分があるとは限りません。そのため、スタッキング機能の位置合わせの処理はそのままでは使えなかったのですが、全く気付いていませんでした。仕方なく、重複部分があるペアーを探して位置合わせする処理に書き換えてやっと完成です。

モザイク合成テスト結果:左は元画像(9分割の様子)、右はモザイク合成結果

課題としては、重複した部分でどちらにマスクをかけるか(どちらを表示するか)というのがあります。撮影時のシーイング変化や画面位置による収差の違いなどで、片側の画像はボケているけど片側はちゃんと写っているという場合があります。手動で合成する画質が良い方を選べますが、私が作った処理では重複があるペアーを見つけた順番でマスクをかける画像が決まる処理になっています。簡単には良いアルゴリズムが思い付かず今のところそのままにしているので、今後使う中で不満に思う様であれば、処理を考えてみようと思っています。

まとめ

DSSの改造がすぐに出来なかった事がきっかけで作成したソフトですが、デッドピクセル除去やダーク,フラットなどの前処理からスタッキングに至る一連の処理を行うものは作成できました。残念ながら目的の1つである「DSSでスタックできない画像もスタック可能にする」は達成できませんでしたが、色々と勉強になりました。

一方で、派生してモザイク合成を行う機能を実装することができました。簡単に作れると思って手を付けましたが、蓋を開けてみると予想以上に時間が掛かってしまいました。とは言え、今後何度もGIMPを使い手作業でモザイク合成することを考えると、かなりの効率アップになります。結果として、スタック処理もモザイク合成処理も作ってよかったと思っています。

結局、このソフトを作った後DSSにデッドピクセル除去の機能を追加することが出来たので、現在はモザイク合成の機能をメインで使っています。また、スタック処理も土星や火星のスタック後の加算合成(自転が早くない惑星のデローテーション代わり)に使っています。このソフトを使った過去記事はこちら(↓)

r77-maabow.hatenablog.com

出来れば位置合わせの処理を改善してDSSで上手くいかない星像が大きい場合でもスタックできるようにしたいと思っていますが、DSSの星検出処理を改造した方が早いかもしれないので、当面はこのままの状態で使おうと思っています。