第18章:视频处理
第18章:視頻處理
- 一、VideoCapture類:
- 1. VideoCapture類中相關方法介紹:
- (1) 初始化:
- (2) 初始化判斷方法:
- (3) 捕獲幀:
- (4) 釋放:
- (5) 屬性設置:
- (6) 捕獲多攝像頭(視頻文件)數據:
- 2. 捕獲攝像頭視頻:
- 3. 播放視頻文件:
- 二、VideoWriter類
- 1. 類函數介紹:
- (1) 構造方法:
- (2) write方法:
- (3) 釋放:
- 2. 保存視頻:
- 三、視頻操作基礎應用:
- 視頻是重要的信息來源,是視覺處理過程中經常要處理的一類信息。
- 視頻是由一系列圖像構成的,這一系列圖像被稱為幀,幀是以固定的時間間隔從視頻中獲取的。
- 獲取(播放)幀的速度稱為幀速率,其單位通常使用“幀/秒”表示,代表在1秒內所出現的幀數,對應的英文是FPS(Frames Per Second)。 如果從視頻中提取出獨立的幀,就可以使用圖像處理的方法對其進行處理,達到處理視頻的目的。
OpenCV提供了cv2.VideoCapture類和cv2.VideoWriter類來支持處理各種類型的視頻文件。不同的操作系統中,它們支持的文件類型可能有所不同,但是在各種操作系統中均支持 AVI格式的視頻文件。
- cv2.VideoCapture:主要要用來讀取處理攝像頭或視頻信息
- cv2.VideoWriter:主要用來寫入視頻
一、VideoCapture類:
OpenCV提供了cv2.VideoCapture類來處理視頻。它既能處理視頻文件又能處理攝像頭信息。
1. VideoCapture類中相關方法介紹:
cv2.VideoCapture 類的常用方法包括初始化、打開、幀捕獲、釋放、屬性設置等,下面對這些函數進行簡單的介紹。
(1) 初始化:
OpenCV中cv2.VideoCapture類的構造方法為cv2.VideoCapture(),用于打開攝像頭并完成攝像頭的初始化工作或者初始化視頻文件對象。
該函數的語法格式為:
-
捕獲對象=cv2.VideoCapture(“需要初始化的對象”)
-
當cv2.VideoCapture()構造方法中傳入的參數是"攝像頭的ID號"時,初始化的是攝像頭對象。
注意,這個參數是攝像設備(攝像頭)的ID編號。其默認值為-1,表示隨機選取一個攝像頭;如果有多個攝像頭,則用數字“0”表示第1個攝像頭,用數字“1”表示第2個攝像頭,以此類推。所以,如果只有一個攝像頭,既可以使用“0”,也可以使用“-1”作為攝像頭ID號。在某些平臺上,如果該參數值為“-1”,OpenCV 會彈出一個窗口,讓用戶手動選擇希望使用的攝像頭。
-
當cv2.VideoCapture()構造方法中傳入的"視頻的文件名"時,初始化的是視頻對象。
注意:可以是視頻的url路徑。
-
捕獲對象:返回值,實例化出的視頻或攝像頭對象。cv2.VideoCapture()構造方法
-
特別注意:視頻處理完以后,要記得釋放攝像頭或視頻對象。
(2) 初始化判斷方法:
- cv2.VideoCapture.open()
- cv2.VideoCapture.isOpened():判斷當前的攝像頭或視頻文件是否初始化成功:
一般情況下,使用cv2.VideoCapture()函數即可完成攝像頭或視頻文件的初始化。有時,為了防止初始化發生錯誤,可以使用函數cv2.VideoCapture.isOpened()來檢查初始化是否成功。該函數的語法格式為:
- retval=cv2.VideoCapture.isOpened()
- 如果成功,則返回值retval為True。
- 如果不成功,則返回值retval為False。
如果攝像頭或視頻文件初始化失敗,可以使用函數 cv2.VideoCapture.open()打開攝像頭或視頻文件。該函數的語法格式為:
- retval=cv2.VideoCapture.open(index)
- index為攝像頭ID號或視頻文件名稱。
- retval為返回值,當攝像頭(或者視頻文件)被成功打開時,返回值為True。
(3) 捕獲幀:
攝像頭(視頻文件)初始化成功后,就可以從攝像頭中捕獲幀信息了。捕獲幀所使用的是函數cv2.VideoCapture.read()。
該函數的語法是:
- retval,image=cv2.VideoCapture.read()
- image:是返回的捕獲到的幀,如果沒有幀被捕獲,則該值為空。
- retval:表示捕獲是否成功,如果成功則該值為True,不成功則為False。
(4) 釋放:
在不需要攝像頭時,要關閉攝像頭。關閉攝像頭使用的是函數 cv2.VideoCapture.release()。該函數的語法是:
- None=cv2.VideoCapture.release()
例如,當前有一個VideoCapture類的對象cap,要將其釋放,可以使用語句:
- cap.release()
(5) 屬性設置:
有時,我們需要獲取 cv2.VideoCapture 類對象的屬性,或是更改該類對象的屬性。
獲取對象屬性: cv2.VideoCapture.get()該函數的語法格式是:
- retval=cv2.VideoCapture.get(propId)
- propId:對應著cv2.VideoCapture類對象的屬性。
例如,有一個cv2.VideoCapture類對象cvc,則:
- 通過cvc.get(cv2.CAP_PROP_FRAME_WIDTH),就能獲取當前幀對象的寬度。
- 通過cvc.get(cv2.CAP_PROP_FRAME_HEIGHT),就能獲取當前幀對象的高度。
設置對象屬性: cv2.VideoCapture.set()該函數的語法是:
- retval=cv2.VideoCapture.set(propId,value)
- propId:對應cv2.VideoCapture類對象的屬性
- value:對應屬性propid的值。
例如,有一個cv2.VideoCapture類對象cvc,則:
- 語句 ret=cvc.set(cv2.CAP_PROP_FRAME_WIDTH,640)將當前幀對象的寬度設置為640像素。
- 語句 ret=cvc.set(cv2.CAP_PROP_FRAME_HEIGHT,480)將當前幀對象的高度設置為480像素。
cv2.VideoCapture類對象的屬性值及含義如表所示。
(6) 捕獲多攝像頭(視頻文件)數據:
- cv2.VideoCapture.grab():捕獲視頻中的下一幀。
- cv2.VideoCapture.retrieve():解碼并返回grab()捕獲的幀。
? 一般情況下,如果需要讀取一個攝像頭的視頻數據,最簡便的方法就是使用函數cv2.VideoCapture.read()。但是,如果需要同步一組或一個多頭(multihead)攝像頭(例如立體攝像頭或 Kinect)的視頻數據時,該函數就無法勝任了。可以把函數 cv2.VideoCapture.read()理解為是由函數 cv2.VideoCapture.grab()和函數 cv2.VideoCapture.retrieve()組成的。函數cv2.VideoCapture.grab()用來指向下一幀,函數cv2.VideoCapture.retrieve()用來解碼并返回一幀。 因此,可以使用函數cv2.VideoCapture.grab()和函數cv2.VideoCapture.retrieve()獲取多個攝像頭的數據。
函數cv2.VideoCapture.grab()用來指向下一幀,其語法格式是:
- retval=cv2.VideoCapture.grab()
如果該函數成功指向下一幀,則返回值retval為True。
函數cv2.VideoCapture.retrieve()用來解碼,并返回函數v2.VideoCapture.grab()捕獲的視頻幀。該函數的語法格式為:
- retval,image=cv2.VideoCapture.retrieve()
- image為返回的視頻幀,如果未成功,則返回一個空圖像。
- retval為布爾型值,若未成功,返回False;否則,返回True。
對于一組攝像頭,可以使用如下代碼捕獲不同攝像頭的視頻幀:
success0=cameraCapture0.grab() success1=cameraCapture1.grab() if success0 and success1:frame0=cameraCapture0.retrieve()frame1=cameraCapture1.retrieve()2. 捕獲攝像頭視頻:
示例:使用cv2.VideoCapture類捕獲攝像頭視頻。
import cv2 import numpy as npcap = cv2.VideoCapture(0)cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1260) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)while cap.isOpened():ret, frame = cap.read()cv2.imshow('frame', frame)c = cv2.waitKey(1)print(c)if c == 97:breakcap.release() cv2.destroyAllWindows()注意:waitKey函數
函數 cv2.waitKey()用來等待按鍵,當用戶按下鍵盤后,該語句會被執行,并獲取返回值。其語法格式為:
- retval=cv2.waitKey([delay])
- retval:表示返回值。如果沒有按鍵被按下,則返回?1;如果有按鍵被按下,則返回該按鍵的ASCII碼。
- delay:表示等待鍵盤觸發的時間,單位是 ms。當該值是負數或者零時,表示無限等待。該值默認為0。
3. 播放視頻文件:
可以通過設置函數cv2.waitKey()中的參數值,來設置播放視頻時每一幀的持續(停留)時間。如果函數cv2.waitKey()中的參數值:
- 較小,則說明每一幀停留的時間較短,視頻播放速度會較快。
- 較大,則說明每一幀停留的時間較長,視頻播放速度會較慢。
注意:視頻文件名稱可以是url
二、VideoWriter類
OpenCV中的cv2.VideoWriter類可以將圖片序列保存成視頻文件,也可以修改視頻的各種屬性,還可以完成對視頻類型的轉換。
1. 類函數介紹:
cv2.VideoWriter類常用的成員方法包括:構造方法、write方法等。本節簡單介紹這兩個常用的方法。
(1) 構造方法:
OpenCV為cv2.VideoWriter類提供了構造函數,用它來實現初始化工作。該函數的語法格式是:
-
< VideoWriter object > =cv2.VideoWriter(filename,fourcc,fps,frameSize[,isColor])
-
filename:指定輸出目標視頻的存放路徑和文件名。如果指定的文件名已經存在,則會覆蓋這個文件。
-
fourcc:表示視頻編/解碼類型(格式)。在OpenCV中用函數cv2.VideoWriter_fourcc()來指定視頻編碼格式。cv2.VideoWriter_fourcc()有4個字符參數。這4個字符參數構成了編/解碼器的“4字標記”,每個編/解碼器都有一個這樣的標記。下面列出幾個常用的標記。
- cv2.VideoWriter_fourcc(‘I’,‘4’,‘2’,‘0’)表示未壓縮的YUV顏色編碼格式,色度子采樣為4:2:0。該編碼格式具有較好的兼容性,但產生的文件較大,文件擴展名為.avi。
- cv2.VideoWriter_fourcc(‘P’,‘I’,‘M’,‘I’)表示 MPEG-1編碼類型,生成的文件的擴展名為.avi。
- cv2.VideoWriter_fourcc(‘X’,‘V’,‘I’,‘D’)表示MPEG-4編碼類型。如果希望得到的視頻大小為平均值,可以選用這個參數組合。該組合生成的文件的擴展名為.avi。
- cv2.VideoWriter_fourcc(‘T’,‘H’,‘E’,‘O’)表示Ogg Vorbis編碼類型,文件的擴展名為.ogv。
- cv2.VideoWriter_fourcc(‘F’,‘L’,‘V’,‘I’)表示Flash視頻,生成的文件的擴展名為.flv。
欲知更多的字符參數組合,可以在網站http://www.fourcc.org上查詢。若參數fourcc為“-1”,則程序運行時會彈出一個對話框,如圖所示。在該對話框中,用戶可以根據自己的需要選擇合適的壓縮程序和壓縮質量。
-
fps:為幀速率。
-
frameSize為每一幀的長和寬。
-
isColor表示是否為彩色圖像。
-
例如,下面的語句完成了cv2.VideoWriter類的初始化工作:
fourcc=cv2.VideoWriter_fourcc(*'XVID') out=cv2.VideoWriter('output.avi',fourcc,20,(1024,768))如果希望通過如圖所示對話框設置編/解碼格式,可以使用語句:
fourcc=-1 out=cv2.VideoWriter('output.avi',fourcc,20,(1024,768))(2) write方法:
cv2.VideoWriter類中的函數cv2.VideoWriter.write()用于寫入下一幀視頻。該函數的語法格式為:
- None=cv2.VideoWriter.write(image)
- image:是要寫入的視頻幀。通常情況下,要求彩色圖像的格式為BGR模式。
在調用該函數時,直接將要寫入的視頻幀傳入該函數即可。
例如,有一個視頻幀為frame,要將其寫入上面的示例中名為out的cv2.VideoWriter類對象內,則使用語句:
out.write(frame)上述語句會把frame傳入名為output.avi的out對象內。
(3) 釋放:
在不需要 cv2.VideoWriter 類對象時,需要將其釋放。釋放該類對象時所使用的是函數cv2.VideoWriter.release()。該函數的語法格式是:
- None=cv2.VideoWriter.release()
例如,當前有一個cv2.VideoWriter類的對象out,可以用以下語句將其釋放:
out.release()
2. 保存視頻:
保存視頻包括創建對象、寫入視頻、釋放對象等多個步驟,下面對各個步驟做簡單的介紹。
創建對象
在創建對象前,首先需要設置好參數。
- 設置好要保存的具體路徑,例如:filename=’‘out.avi’’。
- 使用 cv2.VideoWriter_fourcc()確定編/解碼的類型,例如:
- fourcc=cv2.VideoWriter_fourcc( * ‘XVID’)。
- 確定視頻的幀速率,例如:fps=20。
- 確定視頻的長度和寬度,例如:size=(640,480)。
然后利用上述參數,創建對象。例如:
out=cv2.VideoWriter(filename ,fourcc ,fps ,size)
寫入視頻
用函數cv2.VideoWriter.write()在創建的對象out內寫入讀取到的視頻幀frame。使用的代碼為:out.write(frame)
釋放對象
在完成寫入后,釋放對象out。代碼為:
out.release()
注意: cv2.VideoWriter('output.avi',fourcc, 20.0, (fwidth,fheight)) 中的 fwidth 和 fheight 要和你原始視頻的幀寬度和幀高度一致
三、視頻操作基礎應用:
視頻是由視頻幀構成的,將視頻幀從視頻中提取出,對其使用圖像處理的方法進行處理,就可以達到處理視頻的目的。
示例:提取視頻的Canny邊緣檢測結果。
import cv2cap = cv2.VideoCapture('https://vd3.bdstatic.com/mda-ijurqhuzpqac4fm8/sc/mda-ijurqhuzpqac4fm8.mp4?v_from_s=hkapp-haokan-suzhou&auth_key=1639325601-0-0-8ddbd7ccf330e4d61fbbd0dd792b3eb9&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest=&klogid=2601737365')while cap.isOpened():ret, frame = cap.read()frame = cv2.resize(frame, (640, 320))frame = cv2.Canny(frame, 100, 150)cv2.imshow('frame', frame)c = cv2.waitKey(100)if c == 97:breakcap.release() cv2.destroyAllWindows()總結
- 上一篇: 五一建模之二维纸板切割问题线性整数规划问
- 下一篇: 内核同步机制