Briswell Tech Blog

ブリスウェルのテックブログです

Pythonで降らせる流星群

4月23日は「4月こと座流星群」の極大でした。

明け方から活動ピークを迎えるということで、夜空を見上げましたが...
やはり都会の明るい夜では、星はかけらも見当たりません。ライブカメラの観測に切り替えました。

今年も数は少なかったですが、明るい流れ星もあり、楽しむことができました。あのキラッと流れるのも見た瞬間は心が躍ります。

さて、今回はその感動を分かち合いたく、満天の星空に流星群を降らせてみます。

GitHub - yu4u/shooting-star-generator: Generate synthetic shooting star images

こちらのコードを参考にさせていただきました。ありがとうございました。

1. 流れ星の形状決め

numpy.random.randint(min,max) # min〜maxの範囲の整数
numpy.random.rand() # 0.0以上、1.0未満

# 80〜180の範囲の整数値を取得する場合
length = 80 + np.random.randint(0,100)

# ランダムな角度を取得する場合
theta = 0.7 * pi * np.random.rand() + 0.2 * pi

NumPyのrandomモジュールを使用して、流れ星の表示時間、長さ、明るさ、ヘッドと尾の部分の大きさ、流す角度等を決める乱数値(ランダムな値)を取得します。

2. 流れ星の画像生成

cv2.line(image, start_point, end_point, color, thickness) # 対象画像、開始座標、終了座標、線の色、線の太さ

OpenCVのline関数を使用して、流れ星のヘッドと尾の線を引きます。

画像を繋げたもの(アニメーションGIF)がこちらになります。

Pythonの画像処理ライブラリPillowのsave関数を使うと、アニメーションGIFを作成することができます。

# 画像imに、画像リスト[im1, im2, ...]を追加してアニメーションGIFを作成する場合
im.save('anime.gif', save_all=True, append_images=[im1, im2, ...])

3. 流れ星を回転・移動

cv2.warpAffine(image, affine, (size_x, size_y)) # 対象画像、アフィン変換の行列、出力のサイズ

放射状に見える流星群のイメージに近づけるために、OpenCVのwarpAffine関数を使用して、流す角度や位置を変えます。

4. 背景を透過

# 黒色(R0 G0 B0)のαチャンネル(画素の不透明度)を0にする場合
image[:, :, 3] = np.where(np.all(image == 0, axis=-1), 0, 255)

満天の星空に降らすために、黒色の背景を透過します。

5. 満天の星空と合成

明日の朝、砂浜にほしのかけら落ちているかしら。