2020年算是我個人變動比較大的一年,去年出國念書今年畢業在國外上工,經歷了Remote Learning的下學期,沒有畢業典禮+計畫被打亂的畢業,在空蕩蕩的機場搭飛機回台灣隔離14天,然後又飛回去搬家準備上工。一直沒什麼時間寫下這篇記錄,趕在2020年要過了之前寫完這篇。
這篇算是在防疫旅館做完的Project,目標是做出一個自動追蹤太陽的照相機來照日環蝕。通常要追蹤星體都是用赤道儀,透過跟地球自轉同步的旋轉軸達到跟星體同步,但是沒有用赤道儀有兩個原因:
- 一個是赤道儀貴得要死......貴到不好意思跟老師借來玩
- 第二個是由於地球自轉軸是傾斜的,赤道儀使用之前需要手動對齊北極星+周圍幾個參考星體(因為北極星不是正北),我不確定白天是要怎麼對齊
所以就變這樣了:
長焦鏡頭是Canon FD 100-200 MM f5.6 Lens,RPI HQ Camera一個特色是因為是C/CS mount,所以可以轉接不少老/新鏡頭,我翻了一下Ebay找Cannon FD的長焦就這個好像還可以,買起來才13USD。
好,所以到此照相/機械架構有了,接下來就軟體的架構: 目標是做出一個能夠收集完整解析度之下最高FPS最原始的資料+自動追蹤的架構。
RPI相機資料有四種輸出: 1. MJEPG Encoder 2.H.264 Encoder 3. Raw 4.YUV
大致上整體影像的Pipe Line如下: RAW----->Debayer---->MJEPG or H.264 Encoder
四種輸出就是看你從哪一個Process接出來用
其中H.264有FHD解析度限制,所以只剩下1和3,MJEPG的問題是RPI的Video Encoder不知道為啥Quality調得很低,壓出來的畫質慘不忍睹,第二個問題是MJEPG Encoder雖然沒有解析度限制,但是也是有總pixel的處理限制,雖然解析度不至於頂到但是假如我開VNC調用MJEPG的時候就會撞到。於是只剩下RAW和YUV,RAW檔案的問題是因為是相機底層的資料,我需要先生出相機校正的參數,包含鏡頭變形和色散等等的,老實說我在旅館做不來,加上資料量大小真的恐怖,所以最後試了一下還是用YUV資料。
但是YUV資料量也很恐怖,假設以頂到RPI HQ Camera的CSI-2頻寬上限來算,10 FPS x 4056 x 3040 x 2 = 30Mb/s,要記錄全程大概數小時的資料至少就要數百GB,所以勢必是需要有壓縮的方式,加上太陽濾鏡之後的資料其實就一個大圓以外都黑的,簡單的JPEG就很能壓縮。
我試了在RPI上面跑FFMPEG的結論就是RPI4做不來,那只剩下一個方式:把資料Dump到我的筆電處裡,透過1G的有線網路的話至少可以跑到5FPS,於是就用了raspividyuv+FFMPEG在我的電腦收RPI Dump的資料。
這邊還有一個需要留意的,RPI的ISP生出Frame的時候會帶有timestamp,通常是為了送到Encoder做時間軸用而raspividyuv不會用到,但是因為日蝕是有精確的時間點的,我需要知道每個Frame的時間才好處理,所以我稍微修改了一下raspividyuv把pts紀錄到另外一個檔案裡,事後再把Frame+PTS一同處理。
插曲就是2.5G有線網路其實差不多要開始流行了,我看到2.5G的USB Dongle價錢開始往下壓就買了兩隻想說這下我終於可以把1G的瓶頸暴力的拉到2.5(幾乎是RPI HQ Cam的CSI-2頻寬),結果就是預設的Linux Driver跑不到2.5,很微妙的在1.2左右,原廠的Driver不知道為啥也安裝不了但是還是比1G好一點就硬著頭皮用了
ISP除了Debayer以外還有其他2A的功能,包含Auto Brightness + AWB,Auto Focus因為RPI Camera沒有調焦的功能,所以只能輸出Focus的數字,所以在Setup的時候是先跑輸出Focus找到對焦點之後再開始資料採集。而由於日蝕的亮度變化,所以Auto Brightness有開,而AWB則是固定,我的Cmd如下:
raspividyuv -t 0 -fps 15 --mode 3 -w 4056 -h 3040 -ss 10000 -ISO 100 -ev -10 -mm average -ex spotlight -awb sun -o tcp://169.254.142.200:6667 -pts $DATE_STRING.txt -v
./ffmpeg.exe -f rawvideo -pix_fmt yuv420p -s 4064x3040 -probesize 89M -r 10 -i tcp://0.0.0.0:6667?listen -q:v 5 ".\$((Get-Date).ToString('yyyy-MM-dd_hh-mm-ss'))\img-%08d.jpg" -vf scale=800:600,fps=1 -q:v 2 -f image2 -update 1 udp://169.254.35.220:13991
加上我懶,所以Setup Stream是用power shell script自動跑這兩隻程式
*Note: YUV輸出的時候會自動Padding所以FFMPEG收的時候是4064x3040
以上是資料採集,接下來是自動追蹤
我其實以前也做過太陽的追蹤,2017美西有一次Solar Eclipse,雖然我人在加州只看到日偏食,但是還是有照全程,只是那時候我忘記帶腳架,導致事後資料處裡很麻煩,於是就寫了OpenCV的程式自動擷取太陽出來:
2017年LA日偏食 |
效果不錯,因為太陽濾鏡之後也只剩下一個大圓球很好追,所以就用了OpenCV來追太陽
如果稍微看ffmpeg的指令的話會發現除了壓縮完影像之後,其實我還Copy了Frame然後把解析度調到800x600後送回RPI4,這個資料就是回去給RPI4上面的OpenCV用的,OpenCV抓到太陽的中心點之後就會判斷需不需要移動(因為伺服器馬達有角解析度的限制),然後送指令給伺服器馬達的控制Server。最後為了我自己控制的方便,挖了XBOX的控制器出來讓我能直接手動找太陽+開/關Auto Control。
當然這還是得要先測試個幾次:
很蠢的測試 |
以下是這次日蝕的OpenCV的追蹤結果
有雲的時候邊緣比較拿抓閥值,但是可以直接指定圓的大小就還好,重點是中心點 |
當然還是會有跑掉的時候,所以控制Loop需要有一點De-bounce |
因為下一張就回去了 |
幾張Key Frame
以上,就是在這2020年顛簸的旅程中的一點紀錄
您好,我有很多問題想要請教,我該如何與您聯繫?
回覆刪除這是我的e-mail:afs93raz@gmail.com
直接打在回覆吧
刪除