先日動かしてみたStellarSolver、T-Studioさんによると画像のかなりのエリアが隠れていてもちゃんと星を認識してくれるらしい、ということでぜひとも電子ファインダの方に組み込んでみたいところです。
ということで、これを簡単に使えるラッパークラスを作成しました。
ソースはこちらで公開しています。READMEもなにもない不親切な公開ですがf--;
動かしているのがこちら。画像をロードしたあとStellarSolverを実行すると結果がコンソールに出るだけの簡単なソフトです。
StellarSolverをラップするStellarSolverCtrlクラスのオブジェクト mStellarSolverに対して、実行するのはこれだけ。
3行目:PlateSolveした結果を受け取る関数の指定
5行目:Plate Solveする画像の指定
6行目:PlateSolveで使うIndexファイルの場所の指定
7行目:星の検出やマッチングをするためのパラメータのプリセットの指定
8行目:検索する画角の範囲の指定
9行目:検索する座標の中心の指定
10行目:Plate solve実行
以上です。超簡単。実行して成功なり失敗なりして計算が終了すると、1行目で指定した以下の関数が呼ばれます。ここでは成功のときに結果の座標をコンソールに出力しているだけです。
StellarSolverは星の検出に外部のSExtractorを使ったりとか、座標の計算にastrometry.netを使ったりとか、検出された星の座標を返したりとか様々な機能を持っていますが、自分が使わない機能はバッサリ見えなくして、画像を入れたらその中心座標を返すだけの簡単な機能に絞ってAPIを用意しました。なのでこんなにシンプル。
内蔵のSExtractorやastrometryの計算パラメータはたくさんあります。StellarSolverTesterでは、画面のここで、それらのパラメータを指定できます。

これを全部自分で指定するのは大変ですが、StellarSolverは最初から目的に合わせたプリセットを用意してくれています。今回作ったラッパクラスでは、そのプリセットを選ぶだけにしています。これが上記の計算を実行する関数の7行目。
プリセットそれぞれが何を目的としてパラメータ設定されているか説明は見つけられませんでしたが、設定しているパラメータを見てみると、電子ファインダのような広めの画角の画像でPlate solveするには、PARALLEL_LARGESCALEが良さそうな感じがします。名前的にもそんな感じ。
StellarSolverは並列計算することで高速化することができますが、その並列計算のon/offもこのパラメータの中で選択することができます。プリセットで設定するパラメータの中ででは、名前は「PARALLEL_SOLVING」ですが、これを選ぶとシングルスレッドで、それ以外を選んだ場合は並列計算するかしないかは自動で決まるようです。では自動でどう決まるか、というと、8/行目、9行目の検索範囲の指定をするかしないかで決まるようです。そこのソースはこんな感じ。
画角の範囲と検索中心の両方を指定した場合は並列処理しない。
検索中心だけ指定された場合は検索する画角の範囲について並列処理します。
画角の範囲だけ指定された場合は星の暗さに対して検索を並列処理します。
どちらも指定されていない場合は、画角の範囲について並列処理します。
すなわち、検索範囲を指定されていないパラメータ(==検索範囲が広い)について並列処理する、という思想のようです。
実行した結果がこちら。1280x960の画像に対して、検索する中心と画角の範囲の両方を指定した場合で、約0.17秒でした。これはRPiではなくCore i5 5250U Ubuntu18.04上で実行しているので、RPiだとあと数倍は時間がかかるかと思います。でも速いですね。

ということで、これを簡単に使えるラッパークラスを作成しました。
ソースはこちらで公開しています。READMEもなにもない不親切な公開ですがf--;
動かしているのがこちら。画像をロードしたあとStellarSolverを実行すると結果がコンソールに出るだけの簡単なソフトです。
StellarSolverをラップするStellarSolverCtrlクラスのオブジェクト mStellarSolverに対して、実行するのはこれだけ。
void MainWindow::on_pushButtonSolve_clicked() { connect(&mStellarSolver, &StellarSolverCtrl::onSolverComplete, this, &MainWindow::solverComplete); mStellarSolver.setImage(mImg); mStellarSolver.setIndexPath("/usr/share/astrometry/"); mStellarSolver.setParameterProfile(SSolver::Parameters::ParametersProfile::PARALLEL_LARGESCALE); mStellarSolver.setScale(true, 20, 40); mStellarSolver.setSearchPosition(true, 65, 0); mStellarSolver.startSolve(); }やっていることは、
3行目:PlateSolveした結果を受け取る関数の指定
5行目:Plate Solveする画像の指定
6行目:PlateSolveで使うIndexファイルの場所の指定
7行目:星の検出やマッチングをするためのパラメータのプリセットの指定
8行目:検索する画角の範囲の指定
9行目:検索する座標の中心の指定
10行目:Plate solve実行
以上です。超簡単。実行して成功なり失敗なりして計算が終了すると、1行目で指定した以下の関数が呼ばれます。ここでは成功のときに結果の座標をコンソールに出力しているだけです。
bool MainWindow::solverComplete(bool isSuccess, FITSImage::Solution solution) { disconnect(&mStellarSolver, &StellarSolverCtrl::onSolverComplete, this, &MainWindow::solverComplete); if(isSuccess){ logOutput("RA (J2000)" + StellarSolver::raString(solution.ra)); logOutput("DEC (J2000)"+ StellarSolver::decString(solution.dec)); logOutput("Orientation˚"+ QString::number(solution.orientation)); logOutput("Field Width \'" + QString::number(solution.fieldWidth)); logOutput("Field Height \'"+ QString::number(solution.fieldHeight)); logOutput("PixScale \"" + QString::number(solution.pixscale)); logOutput("Parity" + solution.parity); } return isSuccess; }
StellarSolverは星の検出に外部のSExtractorを使ったりとか、座標の計算にastrometry.netを使ったりとか、検出された星の座標を返したりとか様々な機能を持っていますが、自分が使わない機能はバッサリ見えなくして、画像を入れたらその中心座標を返すだけの簡単な機能に絞ってAPIを用意しました。なのでこんなにシンプル。
内蔵のSExtractorやastrometryの計算パラメータはたくさんあります。StellarSolverTesterでは、画面のここで、それらのパラメータを指定できます。

これを全部自分で指定するのは大変ですが、StellarSolverは最初から目的に合わせたプリセットを用意してくれています。今回作ったラッパクラスでは、そのプリセットを選ぶだけにしています。これが上記の計算を実行する関数の7行目。
プリセットそれぞれが何を目的としてパラメータ設定されているか説明は見つけられませんでしたが、設定しているパラメータを見てみると、電子ファインダのような広めの画角の画像でPlate solveするには、PARALLEL_LARGESCALEが良さそうな感じがします。名前的にもそんな感じ。
typedef enum { FAST_SOLVING, PARALLEL_SOLVING, PARALLEL_LARGESCALE, PARALLEL_SMALLSCALE, ALL_STARS, SMALL_STARS, MID_STARS, BIG_STARS } ParametersProfile;
StellarSolverは並列計算することで高速化することができますが、その並列計算のon/offもこのパラメータの中で選択することができます。プリセットで設定するパラメータの中ででは、名前は「PARALLEL_SOLVING」ですが、これを選ぶとシングルスレッドで、それ以外を選んだ場合は並列計算するかしないかは自動で決まるようです。では自動でどう決まるか、というと、8/行目、9行目の検索範囲の指定をするかしないかで決まるようです。そこのソースはこんな感じ。
if(params.multiAlgorithm == MULTI_AUTO) { if(m_UseScale && m_UsePosition) params.multiAlgorithm = NOT_MULTI; else if(m_UsePosition) params.multiAlgorithm = MULTI_SCALES; else if(m_UseScale) params.multiAlgorithm = MULTI_DEPTHS; else params.multiAlgorithm = MULTI_SCALES; }
画角の範囲と検索中心の両方を指定した場合は並列処理しない。
検索中心だけ指定された場合は検索する画角の範囲について並列処理します。
画角の範囲だけ指定された場合は星の暗さに対して検索を並列処理します。
どちらも指定されていない場合は、画角の範囲について並列処理します。
すなわち、検索範囲を指定されていないパラメータ(==検索範囲が広い)について並列処理する、という思想のようです。
実行した結果がこちら。1280x960の画像に対して、検索する中心と画角の範囲の両方を指定した場合で、約0.17秒でした。これはRPiではなくCore i5 5250U Ubuntu18.04上で実行しているので、RPiだとあと数倍は時間がかかるかと思います。でも速いですね。

コメント
コメント一覧 (2)
かなり空の状態がひどくても解析してくれそうです。(そのような所で星を見たくないという話もありますが(笑))
完成が楽しみですね。
nekomeshi312
が
しました