
こんにちは、Habr。
偶然にも写真と天文学に長い間興味を持っていました。 星空を撮るのが好きです。 夜はほとんど光がないので、本当に美しいものを得るには、かなり長い露出をする必要があります。 しかし、ここで別の問題が発生します-地球が回転するという事実のために、空の星が動きます。 したがって、比較的長い露出では、星は点でなくなり、弧を描き始めます。 深空のオブジェクトを撮影/観察するときにこの動きを補正するために、デバイス- マウントがあります。 残念ながら、現時点ではマウントを購入する方法はないので、自分で質問することにしました-プログラムで同様の効果を実装することは可能ですか?
カットの下にたくさんの写真。 投稿内のすべての写真は私のものであり、(ほとんどすべて)クリック可能で、無料でダウンロードできます。
はじめに
流れ星の問題はこれです:彼らは動きます。 一見したところ、この動きは非常に目立たないように見えるかもしれませんが、比較的短いシャッタースピード(20″ +)でも、星はもはやポイントになりません。空を通る短い弧が見え始めます。

露出〜15 "

露出〜20 '
理論
地球は自身の軸を中心に回転します。 比較的遠い星、この期間は86164.090530833秒です。
したがって、シャッタースピードがわかれば、フレーム内のすべての星が中心からどの程度回転したかを計算できます。 この値によってフレーム全体を反対方向に回転させることでこの回転を補正する場合、すべての星が所定の位置に残る必要があるという考え方です。
すべてが回転する中心を見つける問題は問題ではありません。 極星を見つけるのに十分です-地球の回転軸は非常に近くを通過します。

天球-同じ軸。
実装
このアイデアを実装するために、私はEmgu CV-ラッパーライブラリOpenCV for .NETを使用することにしました。
プログラム全体をペイントするのではなく、基本的な方法についてのみ説明します。
写真が重なり合っている場合、Photoshopでは通常、ブレンドモード:明るくします。 その本質は2つの画像の本質であり、最高の明るさを持つピクセルを選択する1つです。 つまり、2つのソース画像に2つのピクセルがある場合、結果の画像にはより明るいピクセルが含まれます。
Emgu CVでは、このメソッドは既に実装されています。
public Image<TColor, TDepth> Max( Image<TColor, TDepth> img2 )
モード1:回転なしの画像の追加
ここでは複雑なことはありません-リストのすべての写真を交互に重ねるだけです。
List<string> fileNames = (List<string>)filesList; // input Image<Bgr, Byte> image = new Image<Bgr, Byte>(fileNames.First()); // resulting foreach (string filename in fileNames) { Image<Bgr, Byte> nextImage = new Image<Bgr, byte>(filename); image = image.Max(nextImage); nextImage.Dispose(); pictureProcessed(this, new PictureProcessedEventArgs(image)); // updating image in imagebox }
なぜこのモードが必要ですか? 次に、写真を加算した後、星の動きから弧が生じます。 回転の中心(極星)を簡単に見つけることができます。 また、トレース付きの非常に興味深い写真が得られることもあります。
モード2:回転補正による画像の補正
このモードでは、すべてが少し複雑になります。 最初に、撮影中の星の変位の角度を計算する必要があります。 単に持久力に基づいて計算するのはアイデアでしたが、これは最も正確ではないかもしれないことに気付きました。 そのため、 EXIF写真データから撮影時間を引き出します。
Bitmap referencePic = new Bitmap(fileNames.First()); //loading first image byte[] timeTakenRaw = referencePic.GetPropertyItem(36867).Value; // EXIF DateTime taken string timeTaken = System.Text.Encoding.ASCII.GetString(timeTakenRaw, 0, timeTakenRaw.Length - 1); // array to string without last char (newline) DateTime referenceTime = DateTime.ParseExact(timeTaken, "yyyy:MM:d H:m:s", System.Globalization.CultureInfo.InvariantCulture);
順番に。
残りのフレームのカウントを開始するには、撮影開始の瞬間を判断する必要があります。
写真をアップロードして、PropertyItem ID:36867-フレームが受信された日時を取得します。
文字の配列を文字列に変換します(最後の文字は\ nなので、除外します)。
撮影が始まった時間を手に入れました。
後続の各写真について、同じものを見つけ、時間差を使用して回転角度を計算します。
地球の完全な回転にかかる秒数を知っているため 、すべてが単純であると見なされます 。
double secondsShift = (dateTimeTaken - referenceTime).TotalSeconds; double rotationAngle = secondsShift / stellarDay * 360;
アフィン変換によって画像を回転させますが、このために回転行列を計算する必要があります。
幸いなことに、Emgu CVではこれはすべて私たちのために行われます。
RotationMatrix2D<double> rotationMatrix = new RotationMatrix2D<double>(rotationCenter, -rotationAngle, 1); //change rotationAngle sign for CW/CCW
マトリックスがあれば、現在の写真にアフィン変換を適用し、最初のモードのように追加できます。
using (Image<Bgr, Byte> imageToRotate = new Image<Bgr, Byte>(currentPic)) { referenceImage = referenceImage.Max(imageToRotate.WarpAffine<double>(rotationMatrix, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, Emgu.CV.CvEnum.WARP.CV_WARP_FILL_OUTLIERS, background)); }
それだけです。 写真ごとに、これら2つの方法を実行し、何が起こったのかを確認します。
テスト
ソース画像:

27個
テスト1:スタック
すべての写真を1つにオーバーレイした結果。

テスト2:回転とスタック
回転の中心と前方に注目しました。

2番目のテストでは、かなり奇妙な効果が得られました。
1.地球が汚れている-これは正常です。 スターを修正する必要があります。
2.中心の星はそれぞれの場所に残りました。つまり、すべてが正常に機能しました。
3.端の周りに「浮いている」星
なぜこれが起こったのですか? わからない! レンズの歪みのために、星の軌道は円ではなくなり、楕円になったと思います。

露出〜43 '
この写真では、軌跡が理想的な円とは異なることが明確にわかります。これはすべて計算されたものです。
装備品
すべてがキヤノンEF-S 10-22mmでキヤノン7Dで撮影されました。 このレンズには、最適な光学パラメータ、つまり歪みがありません。 したがって、すべてがそれほどスムーズではなかったという事実を私が責めるのは彼です。 次回は、歪みを修正してもう一度テストしてみます。
晴天!
Githubリポジトリ