1. 現象
樹莓派4b/Lenovo_Ubuntu20.04,使用opencv調用usb攝像頭報錯。執行 ret, frame = cap.read() 時終端輸出 select timeout 或者 VIDIOC_DQBUF: Resource temporarily unavailable ,導致無法從攝像頭獲取圖像,frame為空。
2. 設備的索引號錯誤
問題:創建VideoCapture對象時,設備的索引號和正在使用的攝像頭不對應。
解決方法:修改 cap=cv2.VideoCapture(0) 的參數,把0更換成所用攝像頭對應的索引號。如果不知道設備的索引號,可以通過插拔usb攝像頭設備,並輸入命令:
$ ls /dev/video*
通過對比輸出來查看接入設備的索引號。
3. 供電不足
問題:樹莓派usb口供電無法滿足usb攝像頭的供電需求。如果使用其他程序(如fswebcam)可以調用攝像頭,則可以排除這個問題。
解決方法:使用帶額外供電的hub
4. USB設備超時
問題:單純的是usb設備調用比較慢,導致超時無法獲取圖像。
解決方法:V4L2的select()函數的最后一個參數是timeout,timeout是用來設置超時時間的,設置了timeout以后,如果select在沒有文件描述符監視可用的情況下,會等待這個timeout,超過這時間select就會返回錯誤。因此可以通過嘗試修改timeout的值來解決超時問題。
5. 圖像流格式(正解)
問題:樹莓派的CPU/GPU處理能力有限,或者是主流的usb攝像頭驅動uvc有一些限制,最終造成圖像數據無法很好處理。
解決方法:由於opencv使用uvc在樹莓派中讀取usb攝像機流,而cv2.VideoCapture可能默認為未壓縮的流,例如YUYV,因此我們需要將流格式更改為MJPG之類的內容,具體取決於攝像機是否支持該格式。可以通過:
cap.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G'))
完成流的轉換。你可以通過在終端輸入
$ v4l2-ctl -d /dev/video0 --list-formats
查詢你的攝像頭支持哪一種流。
示例代碼:
import cv2
#first camera src
cap = cv2.VideoCapture(0)
# set the format into MJPG in the FourCC format
cap.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G'))
