2017/8/12晚上有英仙座流星雨,不過我當天晚上沒看。隔天看資料的時候,看到它的輻射點似乎和我定點攝影拍的方位一致,心想自己持續架在窗邊的定點攝影機是不是有拍到。昨天就檢視那些影片,果然看到了一些流星還有火流星呢。
不過自己用眼睛看啊看,實在是很累的事情。因為是快轉看的,甚至還會因此而錯失某些路徑短的流星。所以就想應該來寫一個python script來自動搜夜空的流星才是。
分析流程如下:
1.把夜空畫面切出來轉成灰階
2.偵測畫面的灰階值是否有大於某個閾值,如果有代表天空有亮點
3.把偵測到亮點的畫面資料存出來,包括亮點的灰階值、位置、檔案名稱(代表時間),還有把具有亮點的影格也存出來。
最後用眼睛確認那個亮點到底是飛機還是流星,其實這個用程式也能判斷,就是看亮點的移動速度就可以。過程中還發生一個插曲,我的程式分析的影片到凌晨三點多就開始偵測到持續的亮點,以至於資料量爆增,事後去看,原來是那個時間點月亮出來了。
最後我再把影格用imagej處理,匯出影片還有疊圖。影片濃縮了七八個小時的流星片段,要許願就看這片就行了。疊圖(最上面的圖片)則是可以看出輻射點的位置,就在畫面上方。
VIDEO
我想未來可以做一個「流星自動許願機」,就只要在程式裡輸入願望,然後把攝影機對準夜空,就可以去睡覺了,不用熬夜看流星。機器偵測到流星之後,就會自動語音播報願望,保證不會錯失流星,這樣真是太偉大了。
以下就是流星雨的出現資料,打星號為明顯而持續的流星,可能是火流星。
2017/08/12 19:10:37
2017/08/12 20:28:52
2017/08/12 21:30:14
2017/08/12 21:38:19
2017/08/12 21:59:43
2017/08/12 22:06:33 *
2017/08/12 22:37:14
2017/08/12 23:08:32
2017/08/12 23:09:11
2017/08/13 00:12:54
2017/08/13 00:44:56 *
2017/08/13 01:05:42
2017/08/13 01:09:20 *
2017/08/13 01:34:5
2017/08/13 01:39:34
2017/08/13 01:40:24
2017/08/13 01:50:19
2017/08/13 01:50:40
2017/08/13 01:54:35
2017/08/13 02:35:11
2017/08/13 02:38:31 *
2017/08/13 02:46:35
2017/08/13 03:05:29
2017/08/13 03:10:16
2017/08/13 03:12:36
****以下為程式的部份***************************************
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import numpy as np
import cv2
import os
import math
from collections import deque
from operator import itemgetter
def meterFinding(file,video_index):
frameNum = 0
cap = cv2.VideoCapture(file)
#開始處理影格
while(cap.isOpened()):
#現在處理到哪個檔案
print(videofiles[video_index])
ret, frame = cap.read()
#獲知每秒多少影格frame per second
fps = cap.get(cv2.CAP_PROP_FPS)
#影格播完了,就播放下一個,直到video_index到達影片檔案的數量,就停止
if frame is None:
video_index += 1
if video_index >= len(videofiles):
break
cap = cv2.VideoCapture(videofiles[ video_index ])
ret, frame = cap.read()
frameNum=0
#把天空從影格中裁切出來[y1:y2,x1,x2]
sky=frame[0:202,271:1270]
#天空轉換成灰階
gray_sky = cv2.cvtColor(sky, cv2.COLOR_BGR2GRAY)
#找黑天空上的最大灰階值
max_value = max(max(l) for l in gray_sky)
#print(max_value)
#如果最大灰階值大於120,代表有流星,就把檔案路徑印出
if max_value >120:
print(videofiles[video_index])
with open("output.txt", "a") as text_file:
#輸出檔案名稱
text_file.write(videofiles[video_index])
text_file.write("\t")
#輸出秒數
text_file.write(str(int(frameNum/fps)))
text_file.write("\t")
#輸出最大值
text_file.write(str(max_value))
text_file.write("\t")
#輸出流星的位置
ar = np.array(gray_sky)
max_index = np.where(ar == max_value)
#y的位置
text_file.write(str(max_index[0]))
text_file.write("\t")
#X的位置(越大,越靠右,500多在山邊,900多就是在山上)
text_file.write(str(max_index[1]))
text_file.write("\n")
#把畫面存起來
pngName = videofiles[video_index]
pngName = pngName.lstrip("/home/pancala/Desktop/video/test/")
pngName = pngName.rstrip(".mp4")
pngName = pngName.replace('/', '')
pngName = pngName + "_" + str(int(frameNum/fps)) + "_" + str(frameNum)
pngName = pngName + ".png"
cv2.imwrite(pngName,frame)
#if max(gray_sky,key=itemgetter(1))[0] >30:
#print(max(gray_sky,key=itemgetter(1))[0])
#呈現夜空
#cv2.imshow('sky',gray_sky)
frameNum = frameNum +1
#調整waitkey 控制播放速度
k = cv2.waitKey(5) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
video_index = 0
videofiles = []
for dirPath, dirNames, fileNames in sorted(os.walk("/home/pancala/Desktop/video/test")):
for f in sorted(fileNames):
inputFile=os.path.join(dirPath, f)
lastFile=os.path.splitext(f)[-1]
if lastFile==".mp4":
#file='output.mp4'
#把檔案路徑都放進videofiles的list
videofiles.append(inputFile)
#videofiles = [n for n in os.listdir('.') if n[0]=='c' and n[-4:]=='.mp4']
#videofiles = sorted(videofiles, key=lambda item: int( item.partition('.')[0][3:]))
meterFinding(videofiles[0],video_index)