【python+opencv入門學習】四、視訊的讀取、顯示、儲存
本篇文章,將學習如何讀取視訊,顯示視訊和儲存視訊。分別學習從相機和視訊檔案中讀取視訊。主要學習類VideoCapture和類VideoWrter的使用。
環境:Windows 7(64) python 3.6 opencv 3.4.2
一、視訊的讀取與顯示
1.1 瞭解類VideoCapture
對於視訊的讀取,OpenCV提供了介面VideoCapture。要想程式設計實現視訊的讀取與顯示,需要熟悉一下該類的建構函式和成員函式。類VideoCapture的兩個常見建構函式:
<VideoCaputrue object> = cv2.VideoCapture(filename)
功能:開啟視訊檔案。
引數filename:視訊檔名。
<VideoCaputrue object> = cv2.VideoCapture(index)
功能:開啟相機裝置
引數index:相機裝置ID,當只有一個相機時,給0即可。
VideoCapture常用到的成員函式:
retval =cv2.VideoCapture. isOpened()
功能:判斷視訊捕獲是否初始化成功。初始化成功返回true。之前呼叫過VideoCapture的建構函式或者VideoCapture::open()函式成功,就會返回true。
retval=cv2.VideoCapture.open(filename)/cv2.VideoCapture.open(index)
功能:開啟視訊檔案或者相機裝置進行視訊捕獲。
retval = cv2.VideoCapture.get(propId)
功能:得到相機/視訊檔案的各種屬性。propId常見取值如下:
cv2.CAP_PROP_POS_MSEC:視訊檔案的當前位置(ms)
cv2.CAP_PROP_POS_FRAMES:從0開始索引幀,幀位置。
cv2.CAP_PROP_POS_AVI_RATIO:視訊檔案的相對位置(0表示開始,1表示結束)
cv2.CAP_PROP_FRAME_WIDTH:視訊流的幀寬度。
cv2.CAP_PROP_FRAME_HEIGHT:視訊流的幀高度。
cv2.CAP_PROP_FPS:幀率
cv2.CAP_PROP_FOURCC:編解碼器四字元程式碼
cv2.CAP_PROP_FRAME_COUNT:視訊檔案的幀數
cv2.CAP_PROP_FORMAT: retrieve()返回的Mat物件的格式。
cv2.CAP_PROP_MODE:後端專用的值,指示當前捕獲模式
cv2.CAP_PROP_BRIGHTNESS:影象的亮度,僅適用於支援的相機
cv2.CAP_PROP_CONTRAST:影象對比度,僅適用於相機
cv2.CAP_PROP_SATURATION:影象飽和度,僅適用於相機
cv2.CAP_PROP_HUE:影象色調,僅適用於相機
cv2.CAP_PROP_GAIN:影象增益,僅適用於支援的相機
cv2.CAP_PROP_EXPOSURE:曝光,僅適用於支援的相機
cv2.CAP_PROP_CONVERT_RGB:布林標誌,指示是否應將影象轉換為RGB。
retval = cv2.VideoCapture.set(propId,value)
功能:設定屬性,第一個引數是選擇屬性型別,第二個引數是值。
retval,image= cv2.VideoCapture.read([,image])
功能:抓取,解碼並返回下一個視訊幀。返回值為true表明抓取成功。該函式是組合了grab()和retrieve(),這是最方便的方法。如果沒有幀,該函式返回false,並輸出空影象。
retval, image = cv2.VideoCapture.retrieve([, image[, flag]])
功能:解碼並返回抓取的視訊幀。
retval = cv2.VideoCapture.grab()
功能:從視訊檔案或相機中抓取下一幀。true為抓取成功。該函式主要用於多攝像頭時。
none = cv2.VideoCapture.release()
功能:關閉視訊檔案或相機裝置。
1.2 程式設計實現從相機中讀取並顯示視訊
很多時候我們需要從相機獲取實時視訊。本次相機選擇膝上型電腦內建的攝像頭,從中捕獲視訊並顯示它。首先實現捕獲一張圖片。基本思路是首先開啟相機,相機開啟成功後,捕獲一幀影象,然後顯示,最後記的關閉相機。程式碼如下:
import cv2
cap = cv2.VideoCapture(0)#開啟相機
if cap.isOpened():#判斷相機是否開啟成功
ret,frame = cap.read()#捕獲一幀影象
#顯示3s
cv2.imshow('frame',frame)
cv2.waitKey(3000)
cap.release()#關閉相機
cv2.destroyAllWindows()#關閉視窗
可以發現,這與影象的讀取和顯示類似,只不過本次影象是從相機中捕獲的,捕獲是採用的是VideoCapture的成員函式read()。以上功能實現後,可以考慮視訊的讀取和顯示了,也就是連讀從相機中捕獲影象並顯示。在以上程式碼中加個迴圈即可,本次實現採用死迴圈,加了死迴圈就需要考慮怎麼退出迴圈,本次實現採用按鍵盤上的’q’鍵。程式碼如下:
import cv2
cap = cv2.VideoCapture(0)#開啟相機
while(True):
ret,frame = cap.read()#捕獲一幀影象
cv2.imshow('frame',frame)
#判斷按鍵,如果按鍵為q,退出迴圈
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()#關閉相機
cv2.destroyAllWindows()#關閉視窗
以上功能程式設計實現很簡單,有興趣可以嘗試修改相機引數,如影象的大小等,思路是採用set(),也可以程式設計實現獲取相機引數。
1.3 程式設計實現從視訊檔案中讀取並顯示視訊
我們有時候也會從視訊檔案讀取視訊。它的程式設計實現和相機捕獲影象類似,將裝置號改為視訊檔名即可。但是在顯示時,我們需要加一定延遲,不然視訊播放過快。延遲設定正常是25ms。此外,前面採用的是死迴圈,視訊檔案是有長度的,讀取完畢後就應該退出,應該怎麼退出,前面是不是很好奇ret有什麼用,在這裡就用上了,可以用於判斷視訊檔案是否讀取完畢。。程式碼如下:
import cv2
cap = cv2.VideoCapture(‘vtest.avi’)#開啟相機
while( True):
ret,frame = cap.read()#捕獲一幀影象
if ret:
cv2.imshow('frame',frame)
cv2.waitKey(25)
else:
break
cap.release()#關閉相機
cv2.destroyAllWindows()#關閉視窗
可以嘗試改變延時引數,讓視訊慢放或快放。此外有興趣可以考慮採用別的方式判斷視訊檔案是否讀取完了,思路是通過判斷frame是否為空。
二、儲存視訊
2.1 瞭解類VideoWriter
對於視訊的儲存,OpenCV提供了介面VideoWriter。要想程式設計實現儲存視訊,需要熟悉一下該類的建構函式和成員函式。
<VideoWriter object> = cv.VideoWriter( filename, fourcc, fps, frameSize[, isColor] )
引數:
filename:給要儲存的視訊起個名字
fourcc:指定視訊編解碼器的4位元組程式碼。
fps:幀率
frameSize:幀大小
isColor:如果為true,則視訊為彩色,否則為灰度視訊,預設為true
在此再介紹一下fourcc。它是用於壓縮幀的4字元編解碼器程式碼。如VideoWriter :: fourcc('P','I','M','1')是MPEG-1編解碼器,VideoWriter :: fourcc('M','J','P','G ')是一個運動jpeg編解碼器等。要想詳細瞭解fourcc,可以百度搜索進行詳細的學習。
get()、set()、isOpened()、release()等和VideoCapture的成員函式類似,不坐贅述。介紹幾個新的成員函式:
retval = cv2.VideoWriter_fourcc( c1, c2, c3, c4 )
功能:將4字串接為fourcc程式碼。
None = cv.VideoWriter.write( image )
功能:將幀影象儲存為視訊檔案。
2.2 程式設計實現儲存視訊
很多時候我們捕獲視訊,並對其進行幀處理,希望儲存處理後的視訊。要想儲存視訊,首先當然是進行捕獲視訊,程式碼和前面一樣,本次實現儲存相機中捕獲的視訊。將視訊儲存,思路是首先建立VideoWriter類物件,需要指定一些引數,在windows下fourcc取值為DIVX,幀率一般給20,幀大小一般給640*480,建立物件後,採用write()函式儲存幀,儲存完後記得關閉VideoWriter類物件。所以程式碼如下:
import cv2
cap = cv2.VideoCapture(0)#開啟相機
#建立VideoWriter類物件
fourcc = cv2.VideoWriter_fourcc(*’XVID’)
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(True):
ret,frame = cap.read()#捕獲一幀影象
out.write(frame)#儲存幀
cv2.imshow('frame',frame)#顯示幀
#判斷按鍵,如果按鍵為q,退出迴圈
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()#關閉相機
out.release()
cv2.destroyAllWindows()#關閉視窗
該行程式碼fourcc = cv2.VideoWriter_fourcc(*’XVID’)可以改為fourcc = cv2.VideoWriter_fourcc(’X’,’V’,’I’,’D’),他們是一樣的。有興趣可以考慮對每幀畫面進行一個簡單處理後再儲存。
三、總結
本次學習瞭如何從相機或視訊檔案中讀取,顯示並儲存視訊。主要學了兩個類:VideoCapture和VideoWriter。