閑置樹莓派:種朵花然後做延時攝影吧

閑置樹莓派:種朵花然後做延時攝影吧

家裡的樹莓派閑置一段時間了,一直不知道做什麼。最近春天到了,看著小樹苗慢慢長大的樣子,真的很想記錄下來,所以就動手啦!

準備工作

首先請出主角: 一個閑置的樹莓派、攝影機,當然還有花種、花盆。

考慮到樹莓派需要長期開機,最好有一個散熱風扇,某寶有很多這樣的:

image-20220512202238947

攝影機我就用了非常普通的pi camera V2.1,幾十塊錢就可以買到:(圖片來自網路)

image-20220505164628971

搭一個支架,調整焦距

之後需要想辦法把攝影機固定在一個合適的位置。pi Camera 周圍有固定用的小圓孔,加上一個手機支架基本可以固定起來。淘寶上也有賣的,但是不建議買(因為真的沒啥用)。保證攝像角度清楚、穩定是最重要的。我的長這樣:

image-20220516013536265

之後需要調整相機的焦距。Pi camera 是定焦攝影機,理論上來講是不能調焦的,好在這個鏡頭在製作的時候是螺旋擰上去的,這就給了我們操作的空間。

image-20220516014100789

拿一個鑷子對鏡頭上的十字部分旋轉。向右旋轉焦距變小,旋轉半圈基本就差不多了。各位根據自己的距離可以多嘗試

image-20220505165856177

旋轉前vs旋轉後的清晰度變化

這些都做完之後,可以把樹莓派擺好了。選擇位置的時候需要考慮以下幾個問題:

  • 電源:注意樹莓派是沒有電池的,因此需要一個穩壓電源來供電。如果盆栽選在了沒有電源的位置,只能考慮多個充電寶輪流接力,比較麻煩。而且充電寶的電壓一般比額定的2。5V要低一些,可能會出現意外的情況。
  • 散熱。如前面所說的最好整一個風扇。如果溫度過高的話可能拍照會失敗。(使用 cat /sys/class/thermal/thermal_zone0/temp 查看溫度)
  • 防水。這個就不多說了,罩一個塑料布即可。
  • 除此之外最好放在一個有無線網路鏈接的地方,否則每次配置都要連網線,可能會不小心把相機碰歪。

樹莓派配置

下一步開始進入正題。延遲攝影其實就是拍攝一些比較低幀率的影片。我們可以直接拍很多照片,然後手動拼接起來:

首先,拍照片的任務使用一行raspistill命令即可實現,而定時任務的部分可以用crontab來做。拿到照片後,再用opencv或者直接使用ffmpeg把圖片拼起來。思路比較簡單,我們就從最基礎的部分開始:

  • 1 首先需要保證樹莓派的攝影機可以正常工作:

把Pi camera 的排線插進樹莓派的卡槽裡面,然後把卡扣壓緊。(注意這一步最好在關機狀態下做好,否則可能無法識別到攝影機)

然後遠程連接到樹莓派,輸入sudo raspi-config ,進入設置,找到interface options

image-20220509173211020

然後enable camera。

image-20220509173231790

做完這一串之後,使用指令raspistill -v -o test.jpg -ex auto 可以測試自己的攝影機是否完全就緒了。如果正常的話,在用戶空間下應該可以找到一個test.jpg文件。

  • 2 寫一個拍攝腳本。

其實理論上來講根本不用寫腳本,直接用raspistill命令就可以實現了。用腳本實現的好處是可以比較輕鬆的控制拍攝時間和文件名。一般延時攝影的圖片格式考慮使用jpg格式就夠了,否則合成影片的時候壓力會比較大。

#!/bin/bash
DATE=$(date +"%m-%d_%H%M")
raspistill -o /home/pi/flower_pics/$DATE.jpg

把腳本保存之後記得新建對應存放照片的路徑:mkdir /home/pi/flower_pics

  • 3 修改許可權

注意修改腳本的許可權,否則crontab沒辦法自動化執行:chmod +x take_photo.sh

  • 4 配置crontab。

這裡拍照的間隔需要提前考慮好,因為涉及到最後合成影片的品質。

如果拍攝開花的影片,一般間隔可以選擇20s-60s,拍攝2-3個小時;如果只是記錄植物生長則可以間隔更長一點。我的影片大概拍了兩周時間,每20分鐘拍一次,最後影片約25s(考慮到我刪去了夜間的照片,和偶爾一些採光不好的殘次圖)。如果時間比較刁鑽,比如必須是每隔40、50分鐘,這種情況可以在腳本裡面用if條件語句另行做判斷。

輸入crontab -e ,在對應的文件內輸入自己執行的時間,和腳本文件的位置:0,20,40 * * * * sh /home/pi/scripts/take_photo.sh 2>&1

都調整完之後,就可以躺平等著香菜慢慢長大了~

照片的調整&合成

單純的圖片拼接是比較簡單的。使用ffmpeg或者直接上pr都可以實現。但是為了考慮影片的品質,在合成影片前需要做一下簡單的處理。

image-20220508172630521

上面是我出的圖。雖然清晰度還可以,但是很大的一個問題是畫面的曝光程度差別太大了。學校sb宿舍只有早上有陽光直射,導致下午和晚上的香菜都有些不同程度的欠曝,幾張圖片直接拼接到一起會不太舒服,所以需要靠後期,給下午和晚上的照片補光。

考慮到需要對特定時間的圖片批量處理,還是用opencv一條龍操作下來比較方便。

提升亮度方面,一方面增強的是對比度,另一方面考慮畫面的整體亮度,所以主要考慮gamma變化和歸一化處理。各位可以看一下效果自行決定。

  • gamma變換

gamma變換是一個比較好的選擇。對輸入影像的亮度做一個非線性的變換,主要提升暗部的細節,這樣變換得到的結果相比直接增加亮度更自然一些。

\[s = cr^\gamma,{ }r\in[0,1] \]

image-20220511113925540

    gamma = 0.65
    gamma_table=[np.power(x/255.0,gamma)*255.0 for x in range(256)]
    gamma_table=np.round(np.array(gamma_table)).astype(np.uint8)
    img =  cv2.LUT(img,gamma_table)

看下效果:gamma = 0.65

image-20220511182331561

  • 歸一化

實現只需要一行程式碼就夠了:

img = cv2.normalize(img,dst=None,alpha=255,beta=30,norm_type=cv2.NORM_MINMAX)

其中,NORM_MINMAX表示使用歸一化的類型,alpha和beta分別為歸一化後的最大值最小值,也就是max',min'。

\[x' = \frac{x-min}{max-min} * (max' - min') + min' \]

除了NORM_MINMAX之外,也可以選擇切比雪夫距離(cv2.NORM_INF)/歐式距離(cv2.NORM_L2)/曼哈頓距離(cv2.NORM_L1)作為歸一化的距離計算方式。

min_max歸一化:max = 250,min = 20

image-20220511182612976

完整程式碼在這裡

拿到影片之後就很簡單了。打開pr配一段音樂,就完成啦!

結果

Tags: