ふたご座流星群を撮影して画像処理

はじめに

12月最大の流星群はふたご座流星群です。今年2020年は条件がとても良いらしい。条件というと、月が出ていなくて、都市の光源から離れていて、雲ひとつなく晴れていることです。今年は新月と重なっています! 12日土曜日の夜は雲がほとんどなく晴れていたので、ふたご座流星群の撮影をしました。はじめに書きますがそんなに撮れてないです。肉眼ではかなり沢山見えました。

(流星群のピークは月曜ですが幅は一週間くらいあります)

 

f:id:kametaro49:20201213180229j:plain

Take a picture

最近の夜景に対応したスマホでも撮れないこともないですが、まあね?

今回はSonyのカメラであるILCE-7M3と、レンズはFE 16-35mm F2.8 GMを使います。簡単に説明すると、ちょっと大きい一眼カメラと、広角レンズの組み合わせです。

今回の機材

  • カメラ (ILCE-7M, FE 16-35mm F2.8 GM)
  • 三脚
  • ノートPC (Surface)
  • 毛布

撮影した場所が海の側で、深夜になるのでマジ寒いので防寒は必須… 

カメラとノートPCをUSBで繋ぎ、PCから操作します。SonyなのでImagingEdgeというアプリです。これなら撮影中に操作してもカメラが動いたりする心配がない!

設定

15秒おきに以下の設定でインターバル撮影!.jpgの他に生データの.arwも保存。

絞り値 f/2.8
露出時間 10秒
ISO 6400
焦点距離

16mm

まず、絞り値は全開(最小の値)にします。光を多く取り入れるためですね。

露出時間は流星を収めたいので長めに、10秒の間に流れ星が通れば映るということです。長すぎると星が線になってしまいます。(日周運動) ここで赤道儀という、日周運動と同じ速さでカメラを動かすアイテムがありますが、今回はスルー

Amazon.co.jp: Vixen ポータブル赤道儀 星空雲台ポラリエ(WT) ホワイト 355051: カメラ

ISOは光の感度です、センサー側でどれだけ光を増幅するか決められます。高ければより明るく映りますが、高すぎるとノイズまみれになります。

焦点距離はいわゆるズームで、大きいと望遠、小さいと広角ですね。今回は最小にしています。

最後にピントですが、暗いと難しいです。オートフォーカスで運良くピントが合えば、マニュアルに切り替えて触らないようにします。

あとは待ち続けました。(1,2時間)

現像

タイムラプスに編集するもよし、流れ星が映っている写真を探すもよし、結合して星の線を描くもよし。

タイムラプス編

タイムラプスとは、細かく撮影した写真を連続して表示した動画である。動画の早送りと異なり1コマに対する画像があまり圧縮されていないので綺麗。

同じくSonyPlayMemories Homeを使うと簡単。

f:id:kametaro49:20201213173753g:plain

100枚の写真をまとめたタイムラプスGIF

はてなブログの10MB制限に引っかかり解像度は縦横20分の1になっている。流星はぶっちゃけわからん。ホワイトバランスの設定をミスっており若干赤みがかっている。

流星検出編

計300枚ほど撮った写真を一枚づつ見ていく… 割と地味なので見つからない。記事の最初に貼った写真が見つけたもの。写真は6K×4Kなのでそもそもディスプレイの解像度が足りない。プログラムで自動化したいが、日周運動と雲ノイズの扱いがムズそう…専用のソフトもちらほらあるっぽい。

写真結合編

よく見る空が北極星を中心に回転している画像は、露出時間をめっちゃ長くするか、結合するとできる。結合の仕方は簡単に2枚の画像の画素単位で比較し、明るい方を残す「比較明合成」でできる。 GIMPとかでもできる。ただし一枚一枚操作が要るので多分面倒。こっちも専用のソフトはあると思う。でも面倒事はプログラムにやらせよう!(ようやくITっぽくなった)画像処理といえばpythonらしい(ほんとか?

jupyter notebookにて

import cv2
import glob
import matplotlib.pyplot as plt
import numpy as np
maindir = "2020-12-13-RAW\\group3\\"
imgfiles = glob.glob(os.path.join(maindir, '*.JPG'))
im = cv2.imread(imgfiles[0])
for fn in imgfiles:
    nextim = cv2.imread(fn)
    im = np.maximum(nextim,im)
plt.figure(figsize=(6.4 * 34.8 * 3))
plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
cv2.imwrite(str(time.time())+".jpg",im)

OpenCVに比較明合成くらいあるかと探したんですが、見つかりませんでした。普通にnumpyで最大値をとっています。でもこれだと多分R,G,Bでそれぞれ個別に最大値をとっているので、少しおかしいです。見た目はほぼ変わりませんが。ちなみにpyplotはRGBなのにOpenCVがBGRという罠があります。

せっかくなのでJavaでRGBまとめて比較するのを書いた。

    MeteorPic(File dir) {
        File[] files = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dirString name) {
                return name.endsWith(".JPG");
            }
        });
        try {
            BufferedImage sum = ImageIO.read(files[0]);
            ColorModel color = ColorModel.getRGBdefault();
            for (int i = 1i < files.lengthi++) {
                BufferedImage image = ImageIO.read(files[i]);
                for (int x = 0x < sum.getWidth(); x++) {
                    for (int y = 0y < sum.getHeight(); y++) {
                        int sumbright = brightness(colorsumxy);
                        int imagebright = brightness(colorimagexy);
                        if (sumbright < imagebright) {
                            sum.setRGB(xyimage.getRGB(xy));
                        }
                    }
                }
            }

            ImageIO.write(sum"jpg"new File(dir.getName() + ".jpg"));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private int brightness(ColorModel colorBufferedImage imageint xint y) {
        int rgb = image.getRGB(xy);
        int bright = color.getRed(rgb) + color.getGreen(rgb) + color.getBlue(rgb);
        return bright;
    }

numpyでやるよりは遅くなります… 多分並列化してどっこいどっこい。

BufferedImageでは、1ピクセルのRGBがint値一つにまとまって返されます。こいつもBGRで、一色8bitらしい。ColorModelクラスでそこらへんのややこしい話がコンテナ化されている。単純にR+G+Bで比較明合成。

f:id:kametaro49:20201213184324p:plain

Java,右numpy 圧縮率も違うので何もわからん。

f:id:kametaro49:20201213184622j:plain

この中に流星だけ違う方向に流れてすごい!ってなる予定だった。

f:id:kametaro49:20201213185828j:plain

航空機が写り込むと、機体の点滅と撮影のインターバルが写りこむ。雲が流れても写り込む。