教你用python操作攝像頭以及對視頻流的處理
- 實驗介紹
- 知識點
- 視頻錄制
- 視頻編解碼格式
- 視頻錄制演示完整代碼
- 視頻讀取以及特定幀的讀取
- 視頻讀取函式介紹及實作
- 視頻特定幀的讀取(通過幀數間隔截取視頻幀)
- 攝像頭讀取失敗-問題排查
- 實驗總結
- 資源傳送門
- 「?? 感謝大家」
實驗介紹
此次實驗幫助大家利用 OpenCV 去讀取攝像頭的視頻流,你可以直接使用筆記本本身的攝像頭,也可以用 USB 連接直接的攝像頭,如果你在操作程序中,攝像頭讀取失敗, 實驗中還為你提供了幾個問題排查步驟,當然,對視頻進行操作時還需要講解視頻相關的編解碼格式以及特定幀的讀取,在實驗的最后,還提供了 OpenCV 的專案實戰:視頻錄制與視頻讀取,
知識點
- 視頻錄制
- 視頻編解碼格式
- 視頻讀取以及特定幀的讀取
視頻錄制
使用 OpenCV 錄制視頻,主要涉及 OpenCV 的 VideoWrite 物件,錄制視頻的第一步要實體化一個 VideoCapture 物件,用于從攝像頭讀入圖片,創建一個 VideoCapture 物件的代碼如下:
cap = cv2.VideoCapture(0)
類 VideoCapture 的兩個常見建構式:
<VideoCaputrue object> = cv2.VideoCapture(filename)
- 功能:打開視頻檔案;
- 引數filename:視頻檔案名,
<VideoCaputrue object> = cv2.VideoCapture(index)
- 功能:打開相機設備;
- 引數index:相機設備ID,當只有一個相機時,給0即可,
OpenCV 中視頻錄制需要借助 VideoWriter 物件, 將從 VideoCapture 中讀入圖片,不斷地寫入到 VideoWrite 的資料流中,創建 VideoWriter物件的代碼如下:
out = cv2.VideoWriter('video_record.avi', codec, fps, frameSize)
此次實驗選擇筆記本電腦內置的攝像頭,從中捕獲視頻并顯示視頻流,首先實作捕獲一張圖片,基本思路是首先打開相機,再判斷相機是否打開,相機打開成功后,捕獲一幀影像,然后 imshow 顯示,最后關閉相機,具體代碼如下:
import cv2
cap = cv2.VideoCapture(0)
if cap.isOpened():
ret,frame = cap.read()
cv2.imshow('frame',frame)
cv2.waitKey(3000)
cap.release()
cv2.destroyAllWindows()
相機捕獲的一幀影像如圖所示:

視頻編解碼格式
在寫入視頻的時候, 我們必須指定視頻的編解碼格式,這里我們指定為 MJPG 格式,指定視頻編解碼方式為 MJPG 的代碼如下:
codec = cv2.VideoWriter_fourcc(*'MJPG')
在講解視頻的編解碼格式之前,我們先來學習一下 FourCC ,
FourCC 全稱 Four-Character Codes ,代表四字符代碼 (four character code), 它是一個 32 位的標示符,其實就是 typedef unsigned int FOURCC ,FourCC 是一種獨立標示視頻資料流格式的四字符代碼,
FourCC 支持的所有視頻編解碼的格式都可以在 FourCC 官網上查閱,

在指定視頻的編解碼格式為 MJPG 格式之后,我們還需要指定視頻的幀率跟視窗大小,指定寫入幀率為 30 以及視窗大小的代碼如下:
fps = 30.0
frameSize = (640, 480)
初始化 VideoWriter 的時候,將這些引數傳入到其中,并指定輸出視頻檔案的名稱,我們將輸出視頻檔案的名稱命名為 video.avi ,具體代碼如下:
out = cv2.VideoWriter('video.avi', codec, fps, frameSize)
視頻錄制演示完整代碼
接下來,就是要不斷的從 VideoCapture 中讀入圖片,然后寫入到VideoWrite 的資料流中,不斷的向視頻輸出流寫入幀影像的代碼如下:
out.write(frame)
在視頻錄制結束后,為了節省資源,我們需要釋放已經占用的資源,具體代碼實作如下:
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-結束視頻錄制")
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()
視頻讀取以及特定幀的讀取
視頻讀取函式介紹及實作
讀入視頻的時候,我們仍然需要使用 VideoCapture 物件,只不過傳入的不再是攝像頭的 ID 了,需要改成視頻檔案的路徑,讀取視頻流的時候可以逐幀讀取捕獲實作的影像,此時讀入視頻流的代碼如下:
cap = cv2.VideoCapture('video.avi')
OpenCV 提供了介面 VideoWriter 用于視頻的保存,具體函式表示如下:
<VideoWriter object> = cv.VideoWriter( filename, fourcc, fps, frameSize[, isColor] )
函式引數:
-
filename:給要保存的視頻起個名字;
-
fourcc:指定視頻編解碼器的4位元組代碼;
【(‘P’,‘I’,‘M’,‘1’)是MPEG-1編解碼器】
【(‘M’,‘J’,‘P’,'G ')是一個運動jpeg編解碼器】 -
fps:幀率;
-
frameSize:幀大小,
從視頻檔案中播放視頻,更改相機索引與視頻檔案名, 在顯示幀時,選擇適當的 cv2.waitKey()時間,如果該值太小,視頻會非常快,如果它太大,視頻會很慢(這可以用來慢動作顯示視頻), 正常情況下,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()
視頻寫入完成,命名為 video.avi ,結果展示如下:


視頻特定幀的讀取(通過幀數間隔截取視頻幀)
通過視頻的幀數間隔截取視頻的每一幀,自己設定幀間隔為 20 ,即每隔 20 幀截取一幀影像,并將我們截取的每一幀保存到我們自定義的檔案夾中,這里保存的檔案夾為代碼存在的路徑下 capture_image 檔案夾里,具體實作的代碼如下:
import cv2
cap = cv2.VideoCapture("video.avi")
c = 1
frameRate = 20
while(True):
ret, frame = cap.read()
if ret:
if(c % frameRate == 0):
print("開始截取視頻第:" + str(c) + " 幀")
cv2.imwrite("./capture_image/" + str(c) + '.jpg', frame)
c += 1
cv2.waitKey(0)
else:
print("所有幀都已經保存完成")
break
cap.release()
運行結果如下,將展示我們截取的視頻幀數間隔:

如圖為視頻截取的最后一幀影像:

注意:讀入視頻檔案和保存圖片的路徑,都要使用“\\”,使用“/”或者“\”會出現打開檔案報錯,
攝像頭讀取失敗-問題排查
如果你運行上文的源代碼的時候,出現報錯,
你可以按照下面提供的思路自行檢查一下,
- 驅動問題 有的攝像頭可能存在驅動問題,需要安裝相關驅動,或者查看攝像頭是否具有UAC免驅協議,
- USB介面兼容性問題 USB2.0介面接了一個USB3.0的攝像頭,也是不支持的(這只針對用 USB 連接攝像頭的,用筆記本自帶的攝像頭可忽略),
- 設備掛載問題 攝像頭沒有被掛載,如果是虛擬機需要手動勾選設備,
- 硬體問題 在就是檢查一下USB線跟電腦USB介面,
- 視頻壓縮格式的問題 部分視頻壓縮格式在OpenCV中不支持,
實驗總結
初學者可能對 OpenCV 處理會很頭暈,因為它涉及到的函式有很多,每一個函式會有不同的用法,如果要通過 OpenCV 去呼叫攝像頭完成任務,就需要去學習這些內容,此次實驗從視頻錄取、視頻讀取再到視頻特定幀的讀取一步一步帶你實作,里面對相關函式也講解的非常透徹,相關引數也進行了說明,涉及到實踐的地方已經幫你把相關的源代碼給出,學習不會有障礙,當然,實驗最后也給出了攝像頭讀取失敗問題的排查步驟,讓你在學習的程序中能夠得到滿足,
資源傳送門
關注【做一個柔情的程式猿】公眾號
在【做一個柔情的程式猿】公眾號后臺回復 【python資料】【2020秋招】 即可獲取相應的驚喜哦!
「?? 感謝大家」
點贊支持下吧,讓更多的人也能看到這篇內容(收藏不點贊,都是耍流氓 -_-)
歡迎在留言區與我分享你的想法,也歡迎你在留言區記錄你的思考程序,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/139769.html
標籤:其他
上一篇:直播一對一視頻直播聊天
