視頻錄制與視頻讀取¶
概要¶
本期阿凱講解了使用opencv錄制視頻與視頻讀取的相關操作。主要涉及opencv的VideoWrite
對象的講解。
注意OpenCV只支持avi的格式,而且生成的視頻文件不能大于2GB,而且不能添加音頻。
keywords 視頻錄制 視頻讀取
1. 視頻錄制Write¶
1.1 效果演示效果¶
完整代碼,請查看下文【源碼】視頻錄制, 復制到本地,并命名為VideoWrite.py
后續內容是對此代碼的詳細講解, 可跳過。
1.2 VideoWriter¶
錄制視頻的第一步要實例化一個VideoCapture
對象。 用于從USB攝像頭讀入圖片。
# 創建一個VideoCapture對象 cap = cv2.VideoCapture(0)
opencv中視頻錄制需要借助VideoWriter
對象, 將從VideoCapture
中讀入圖片,不斷地寫入到VideoWrite
的數據流中。
# 指定視頻編解碼方式為MJPG codec = cv2.VideoWriter_fourcc(*'MJPG') fps = 20.0 # 指定寫入幀率為20 frameSize = (640, 480) # 指定窗口大小 # 創建 VideoWriter對象 out = cv2.VideoWriter('video_record.avi', codec, fps, frameSize)
1.3 視頻錄制的插件依賴¶
opencv的視頻錄制依賴第三方插件,在不同的操作系統使用的視頻錄制插件如下
操作系統 | 視頻錄制插件 |
---|---|
Linux | FFMPEG |
Windows | FFMPEG ,VFW |
MacOSX | QTKit |
這些都在opencv中封裝好了,所以我們不需要去了解底層的內容。
1.4 視頻編解碼格式¶
在寫入視頻的時候, 我們必須指定視頻的編解碼格式,這里我們指定為MJPG
格式。
codec = cv2.VideoWriter_fourcc(*'MJPG')
關于FourCC
FourCC全稱Four-Character Codes,代表四字符代碼 (four character code), 它是一個32位的標示符,其實就是typedef unsigned int FOURCC;
, 是一種獨立標示視頻數據流格式的四字符代碼。
FourCC支持的所有視頻編解碼的格式都可以在FourCC官網上查閱。
同時,我們還需要指定視頻的幀率跟窗口大小。
fps = 20.0 # 指定寫入幀率為20 frameSize = (640, 480) # 指定窗口大小
初始化VideoWriter
的時候,將這些參數傳入到其中。并指定輸出視頻文件的名稱video_record.avi
# 創建 VideoWriter對象 out = cv2.VideoWriter('video_record.avi', codec, fps, frameSize)
1.5 追加幀¶
接下來,就是要不斷的從VideoCapture
中讀入圖片,然后寫入到VideoWrite
的數據流中。
# 不斷的向視頻輸出流寫入幀圖像 out.write(frame)
1.6 資源釋放¶
在錄制結束后,我們要釋放資源:
# 釋放資源 cap.release() out.release()
1.7【源碼】視頻錄制¶
VideoWrite.py
#-*- coding: UTF-8 -*- ''' 功能描述:視頻錄制演示代碼 作者:阿凱@1Z實驗室 網站:www.1z1b.com QQ交流群 218214240 ''' import numpy as np import cv2 # 創建一個VideoCapture對象 cap = cv2.VideoCapture(0) # 指定視頻編解碼方式為MJPG codec = cv2.VideoWriter_fourcc(*'MJPG') fps = 20.0 # 指定寫入幀率為20 frameSize = (640, 480) # 指定窗口大小 # 創建 VideoWriter對象 out = cv2.VideoWriter('video_record.avi', codec, fps, frameSize) print("按鍵Q-結束視頻錄制") while(cap.isOpened()): ret, frame = cap.read() # 如果幀獲取正常 if ret==True: # 鏡像反轉 flip # frame = cv2.flip(frame, -1) # 不斷的向視頻輸出流寫入幀圖像 out.write(frame) # 在窗口中展示畫面 cv2.imshow('frame',frame) if cv2.waitKey(1) == ord('q'): break else: break # 釋放資源 cap.release() out.release() cv2.destroyAllWindows()
2. 視頻讀取 Read¶
讀入視頻的時候,我們仍然需要使用VideoCapture
對象,只不過傳入的不再是USB攝像頭的ID了,需要改成視頻文件的路徑。
# 讀入視頻流 cap = cv2.VideoCapture('demo.avi')
2.1 讀取視頻¶
2.1.1 效果演示¶
2.1.2 【源碼】視頻讀取¶
VideoReadFromFile.py
#-*- coding: UTF-8 -*- ''' 讀入視頻并在窗口展示 作者:阿凱@1Z實驗室 網站:www.1z1b.com QQ交流群 218214240 ''' import numpy as np import cv2 # 讀入視頻流 cap = cv2.VideoCapture('demo.avi') while(True): # 逐幀獲取畫面 # ret ? 畫面是否獲取成功 ret, frame = cap.read() if ret: # 在窗口展示視頻 cv2.imshow('frame',frame) else: print("視頻讀取完畢或者視頻路徑異常") break # 這里做一下適當的延遲,每幀延時0.1s鐘 if cv2.waitKey(100) & 0xFF == ord('q'): break # 釋放資源 cap.release() cv2.destroyAllWindows()
2.2 讀取特定幀¶
2.2.1 效果演示¶
2.2.2【源碼】讀取視頻的特定幀¶
VideoReadFromFileSepecificFrame.py
#-*- coding: UTF-8 -*- ''' 獲取特定幀數的照片 作者:阿凱@1Z實驗室 網站:www.1z1b.com ''' import numpy as np import cv2 # 讀取視頻流 cap = cv2.VideoCapture('demo.avi') # 獲取視頻所有的幀數 amount_of_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT) # 設置當前幀的位置 amount_of_frames-1 代表最后一幀 cap.set(cv2.CAP_PROP_POS_FRAMES, amount_of_frames-1) ret, img = cap.read() if ret: cv2.imwrite('last_frame.png', img)