從攝像頭獲取視頻
OpenCV提供了非常簡單的接口可用于讀取攝像頭中的視頻流。要獲取視頻,首先需要使用cv.VideoCapture()創建一個VideoCapture對象。其創建參數可以是設備號、視頻文件名、圖片序列、視頻流的URL,細節可看文檔。
使用設備號創建對象時,傳入0即可打開系統中默認攝像頭。之后就可以使用cv.VideoCapture.read()方法按幀來獲取視頻圖片。使用cv.imshow()顯示圖片。操作結束后需要使用cv.VideoCapture.release()方法釋放該VideoCapture對象。
import numpy as np
import cv2 as cv
# 創建VideoCapture,傳入0即打開系統默認攝像頭
cap = cv.VideoCapture(0)
while(True):
# 讀取一幀,read()方法是其他兩個類方法的結合,具體文檔
# ret為bool類型,指示是否成功讀取這一幀
ret, frame = cap.read()
# 就是個處理一幀的例子,這里轉為灰度圖
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 不斷顯示一幀,就成視頻了
# 這里沒有提前創建窗口,所以默認創建的窗口不可調整大小
# 可提前使用cv.WINDOW_NORMAL標簽創建個窗口
cv.imshow('frame',gray)
# 若沒有按下q鍵,則每1毫秒顯示一幀
if cv.waitKey(1) & 0xFF == ord('q'):
break
# 所有操作結束后不要忘記釋放
cap.release()
cv.destroyAllWindows()
如果終端不斷輸出“opencv Camera dropped frame!”,就說明讀取幀的頻率過快,增大cv.waitKey()的傳入值就好了。
有的時候,VideoCapture對象可能沒有被成功初始化,這時操作該對象會發生錯誤。可以使用cv.VideoCapture.isOpened()方法來判斷該攝像頭是否被打開。如果沒有打開,可以使用cv.VideoCapture.open()方法來打開攝像頭。
可以使用cv.VideoCapture.get()方法來獲取已打來攝像頭的屬性。對應的可以使用cv.VideoCapture.set()方法來設置這些屬性的值。比如,對于上面打開的攝像頭,可以使用cap.get(cv.CAP_PROP_FRAME_WIDTH)和cap.get(cv.CAP_PROP_FRAME_HEIGHT)來分別獲取幀的寬和高。使用ret = cap.set(cv.CAP_PROP_FRAME_WIDTH,320)和ret = cap.set(cv.CAP_PROP_FRAME_HEIGHT,240)將幀的寬和高分別設為320和240。
操作視頻文件
使用視頻文件名創建VideoCapture對象,即可打開對應的視頻文件。在顯示幀時,注意使用cv.waitKey()來控制幀率,通常25毫秒是可以的。示例代碼如下:
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('vtest.avi')
while(cap.isOpened()):
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
cv.imshow('frame',gray)
if cv.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv.destroyAllWindows()
我打開了一個mp4文件來顯示,但是效果并不好,弄得電腦很卡,不知道為什么。沒有攝像頭的流暢。
保存視頻
處理了視頻的每一幀之后,想要將其保存下來。對于圖片使用cv.imwrite()就可以了,但對于視頻,多需要一些操作。
首先需要使用cv.VideoWriter()創建一個VideoWriter對象,創建對象時需要指定輸出文件名、FourCC編碼、fps和幀的大小,最后一個參數為isColor,其指定了是彩色幀(True)還是灰度幀(False),默認為True。
FourCC是一個四字節碼,用于指定視頻的編碼方式。全部可用的FourCC在這里:fourcc.org,它是平臺相關的。
對于MJPG,可以使用cv.VideoWriter_fourcc('M','J','P','G')或cv.VideoWriter_fourcc(*'MJPG')來設置FourCC。下面代碼從攝像頭中采集圖片,左右翻轉后存入視頻文件:
import numpy as np
import cv2 as cv
cv.namedWindow('frame', cv.WINDOW_NORMAL)
cap = cv.VideoCapture(0)
# 這里如果不設置窗口大小的話
# 存儲視頻文件時會出錯
cap.set(cv.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv.CAP_PROP_FRAME_HEIGHT, 480)
fourcc = cv.VideoWriter_fourcc(*'MJPG')
out = cv.VideoWriter('output.mp4',fourcc, 20.0, (640,480))
while cap.isOpened():
ret, frame = cap.read()
if ret==True:
frame = cv.flip(frame,1)
out.write(frame)
cv.imshow('frame',frame)
if cv.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv.destroyAllWindows()
雖然運行上面代碼可以得到一個mp4文件,但是用播放器播放時確說無法打開,不知道是為什么。