教你如何用python操作攝像頭以及對(duì)視頻流的處理
實(shí)驗(yàn)介紹
此次實(shí)驗(yàn)幫助大家利用 OpenCV 去讀取攝像頭的視頻流,你可以直接使用筆記本本身的攝像頭,也可以用 USB 連接直接的攝像頭。如果你在操作過(guò)程中,攝像頭讀取失敗, 實(shí)驗(yàn)中還為你提供了幾個(gè)問(wèn)題排查步驟。當(dāng)然,對(duì)視頻進(jìn)行操作時(shí)還需要講解視頻相關(guān)的編解碼格式以及特定幀的讀取。在實(shí)驗(yàn)的最后,還提供了 OpenCV 的項(xiàng)目實(shí)戰(zhàn):視頻錄制與視頻讀取。
知識(shí)點(diǎn)
- 視頻錄制
- 視頻編解碼格式
- 視頻讀取以及特定幀的讀取
視頻錄制
使用 OpenCV 錄制視頻,主要涉及 OpenCV 的 VideoWrite 對(duì)象。錄制視頻的第一步要實(shí)例化一個(gè) VideoCapture 對(duì)象,用于從攝像頭讀入圖片。創(chuàng)建一個(gè) VideoCapture 對(duì)象的代碼如下:
cap = cv2.VideoCapture(0)
類 VideoCapture 的兩個(gè)常見(jiàn)構(gòu)造函數(shù):
<VideoCaputrue object> = cv2.VideoCapture(filename)
功能:打開(kāi)視頻文件;
參數(shù)filename:視頻文件名。
<VideoCaputrue object> = cv2.VideoCapture(index)
功能:打開(kāi)相機(jī)設(shè)備;
參數(shù)index:相機(jī)設(shè)備ID,當(dāng)只有一個(gè)相機(jī)時(shí),給0即可。
OpenCV 中視頻錄制需要借助 VideoWriter 對(duì)象, 將從 VideoCapture 中讀入圖片,不斷地寫(xiě)入到 VideoWrite 的數(shù)據(jù)流中。創(chuàng)建 VideoWriter對(duì)象的代碼如下:
out = cv2.VideoWriter('video_record.avi', codec, fps, frameSize)
此次實(shí)驗(yàn)選擇筆記本電腦內(nèi)置的攝像頭,從中捕獲視頻并顯示視頻流。首先實(shí)現(xiàn)捕獲一張圖片。基本思路是首先打開(kāi)相機(jī),再判斷相機(jī)是否打開(kāi),相機(jī)打開(kāi)成功后,捕獲一幀圖像,然后 imshow 顯示,最后關(guān)閉相機(jī)。具體代碼如下:
import cv2 cap = cv2.VideoCapture(0) if cap.isOpened(): ret,frame = cap.read() cv2.imshow('frame',frame) cv2.waitKey(3000) cap.release() cv2.destroyAllWindows()
相機(jī)捕獲的一幀圖像如圖所示:
視頻編解碼格式
在寫(xiě)入視頻的時(shí)候, 我們必須指定視頻的編解碼格式,這里我們指定為 MJPG 格式。指定視頻編解碼方式為 MJPG 的代碼如下:
codec = cv2.VideoWriter_fourcc(*'MJPG')
在講解視頻的編解碼格式之前,我們先來(lái)學(xué)習(xí)一下 FourCC 。
FourCC 全稱 Four-Character Codes ,代表四字符代碼 (four character code), 它是一個(gè) 32 位的標(biāo)示符,其實(shí)就是 typedef unsigned int FOURCC 。FourCC 是一種獨(dú)立標(biāo)示視頻數(shù)據(jù)流格式的四字符代碼。
FourCC 支持的所有視頻編解碼的格式都可以在 FourCC 官網(wǎng)上查閱。
在指定視頻的編解碼格式為 MJPG 格式之后,我們還需要指定視頻的幀率跟窗口大小。指定寫(xiě)入幀率為 30 以及窗口大小的代碼如下:
fps = 30.0 frameSize = (640, 480)
初始化 VideoWriter 的時(shí)候,將這些參數(shù)傳入到其中。并指定輸出視頻文件的名稱。我們將輸出視頻文件的名稱命名為 video.avi ,具體代碼如下:
out = cv2.VideoWriter('video.avi', codec, fps, frameSize)
視頻錄制演示完整代碼
接下來(lái),就是要不斷的從 VideoCapture 中讀入圖片,然后寫(xiě)入到VideoWrite 的數(shù)據(jù)流中。不斷的向視頻輸出流寫(xiě)入幀圖像的代碼如下:
out.write(frame)
在視頻錄制結(jié)束后,為了節(jié)省資源,我們需要釋放已經(jīng)占用的資源,具體代碼實(shí)現(xiàn)如下:
cap.release() out.release()
視頻錄制演示完整代碼如下:
import numpy as np import cv2 cap = cv2.VideoCapture(0) codec = cv2.VideoWriter_fourcc(*'MJPG') fps = 20.0 frameSize = (640, 480) out = cv2.VideoWriter('video.avi', codec, fps, frameSize) print("按鍵Q-結(jié)束視頻錄制") while(cap.isOpened()): ret, frame = cap.read() if ret==True: out.write(frame) cv2.imshow('frame',frame) if cv2.waitKey(1) == ord('q'): break else: break cap.release() out.release() cv2.destroyAllWindows()
視頻讀取以及特定幀的讀取
視頻讀取函數(shù)介紹及實(shí)現(xiàn)
讀入視頻的時(shí)候,我們?nèi)匀恍枰褂?VideoCapture 對(duì)象,只不過(guò)傳入的不再是攝像頭的 ID 了,需要改成視頻文件的路徑。讀取視頻流的時(shí)候可以逐幀讀取捕獲實(shí)現(xiàn)的圖像。此時(shí)讀入視頻流的代碼如下:
cap = cv2.VideoCapture('video.avi')
OpenCV 提供了接口 VideoWriter 用于視頻的保存,具體函數(shù)表示如下:
cap = cv2.VideoCapture('video.avi')
函數(shù)參數(shù):
- filename:給要保存的視頻起個(gè)名字;
- fourcc:指定視頻編解碼器的4字節(jié)代碼;
-
【(‘P',‘I',‘M',‘1')是MPEG-1編解碼器】
-
【(‘M',‘J',‘P','G ')是一個(gè)運(yùn)動(dòng)jpeg編解碼器】
-
- fps:幀率;
- frameSize:幀大小。
從視頻文件中播放視頻,更改相機(jī)索引與視頻文件名。 在顯示幀時(shí),選擇適當(dāng)?shù)?cv2.waitKey()
時(shí)間,如果該值太小,視頻會(huì)非常快,如果它太大,視頻會(huì)很慢(這可以用來(lái)慢動(dòng)作顯示視頻)。 正常情況下,25 毫秒即可。具體視頻讀取的源代碼如下:
import numpy as np import cv2 cap = cv2.VideoCapture('video.avi') while(True): ret, frame = cap.read() if ret: cv2.imshow('frame',frame) else: print("視頻讀取完畢或者視頻路徑異常") break if cv2.waitKey(25) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
視頻寫(xiě)入完成,命名為 video.avi ,結(jié)果展示如下:
視頻特定幀的讀?。ㄍㄟ^(guò)幀數(shù)間隔截取視頻幀)
通過(guò)視頻的幀數(shù)間隔截取視頻的每一幀,自己設(shè)置幀間隔為 20 ,即每隔 20 幀截取一幀圖像,并將我們截取的每一幀保存到我們自定義的文件夾中,這里保存的文件夾為代碼存在的路徑下 capture_image 文件夾里。具體實(shí)現(xiàn)的代碼如下:
import cv2 cap = cv2.VideoCapture("video.avi") c = 1 frameRate = 20 while(True): ret, frame = cap.read() if ret: if(c % frameRate == 0): print("開(kāi)始截取視頻第:" + str(c) + " 幀") cv2.imwrite("./capture_image/" + str(c) + '.jpg', frame) c += 1 cv2.waitKey(0) else: print("所有幀都已經(jīng)保存完成") break cap.release()
運(yùn)行結(jié)果如下,將展示我們截取的視頻幀數(shù)間隔:
如圖為視頻截取的最后一幀圖像:
注意:讀入視頻文件和保存圖片的路徑,都要使用“\\”,使用“/”或者“\”會(huì)出現(xiàn)打開(kāi)文件報(bào)錯(cuò)。
攝像頭讀取失敗-問(wèn)題排查
如果你運(yùn)行上文的源代碼的時(shí)候,出現(xiàn)報(bào)錯(cuò)。
你可以按照下面提供的思路自行檢查一下。
- 驅(qū)動(dòng)問(wèn)題 有的攝像頭可能存在驅(qū)動(dòng)問(wèn)題,需要安裝相關(guān)驅(qū)動(dòng),或者查看攝像頭是否具有UAC免驅(qū)協(xié)議。
- USB接口兼容性問(wèn)題 USB2.0接口接了一個(gè)USB3.0的攝像頭,也是不支持的(這只針對(duì)用 USB 連接攝像頭的,用筆記本自帶的攝像頭可忽略)。
- 設(shè)備掛載問(wèn)題 攝像頭沒(méi)有被掛載,如果是虛擬機(jī)需要手動(dòng)勾選設(shè)備。
- 硬件問(wèn)題 在就是檢查一下USB線跟電腦USB接口。
- 視頻壓縮格式的問(wèn)題 部分視頻壓縮格式在OpenCV中不支持。
實(shí)驗(yàn)總結(jié)
初學(xué)者可能對(duì) OpenCV 處理會(huì)很頭暈,因?yàn)樗婕暗降暮瘮?shù)有很多,每一個(gè)函數(shù)會(huì)有不同的用法,如果要通過(guò) OpenCV 去調(diào)用攝像頭完成任務(wù),就需要去學(xué)習(xí)這些內(nèi)容。此次實(shí)驗(yàn)從視頻錄取、視頻讀取再到視頻特定幀的讀取一步一步帶你實(shí)現(xiàn),里面對(duì)相關(guān)函數(shù)也講解的非常透徹,相關(guān)參數(shù)也進(jìn)行了說(shuō)明,涉及到實(shí)踐的地方已經(jīng)幫你把相關(guān)的源代碼給出,學(xué)習(xí)不會(huì)有障礙。當(dāng)然,實(shí)驗(yàn)最后也給出了攝像頭讀取失敗問(wèn)題的排查步驟,讓你在學(xué)習(xí)的過(guò)程中能夠得到滿足。
到此這篇關(guān)于教你如何用python操作攝像頭以及對(duì)視頻流的處理的文章就介紹到這了,更多相關(guān)python操作攝像頭及視頻流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python+Tesseract OCR實(shí)現(xiàn)截屏識(shí)別文字
pytesseract Python常用pytesseract進(jìn)行圖片上的文字識(shí)別,本文主要介紹了python+Tesseract?OCR實(shí)現(xiàn)截屏識(shí)別文字,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11