OpenCV學習筆記之五:視頻讀取寫入

用 OpenCV 開發難免會針對 Camera 或者是 Video 做處理,有的時候需要將畫面保留下來,這個時候最佳方案是保存成一個 .avi 的文件。

OpenCV 底層是用 FFMEPG 進行多媒體開發的,所以 OpenCV 它的長項不在於此,它只是提供了這種能力而已,如果要針對多媒體文件做複雜的處理,推薦的還是 FFMEPG 專業庫。

OpenCV 用來創建視頻文件的類是 VideoWriter。

但首先,給大家普及一些視頻類相關的知識點。

1. 文件後綴名

我們一般都知道視頻文件是 .mp4、.3gp、.rmvb 等等格式的,但一個文件取這樣的後綴名是爲了告訴用戶或者操作系統,它的內容是什麼格式的。我們也可以將 rmvb 格式的文件取名爲 ***.avi。後綴的目的是爲了方便用專業的工具或者軟件操作它們。

2. 文件格式

我們可以將一個視頻文件看做一個容器。

簡單地說就是可以看做是一個盒子。

這個盒子裏面有視頻畫面數據、音頻數據、字幕數據等等。

3. 編碼格式

視頻容器中,一般有視頻和音頻數據,它們採取的編碼方式不一樣。

視頻常見的編碼方式通常有: x264、h264、mpeg-4

音頻常見的編碼方式通常有: mp3、AAC、flac

編碼的目的主要是爲了高效存儲和傳輸,如果你不採用編碼壓縮的話,那麼視頻可以看做是一系列的圖片序列,體積會非常大。

4. 編碼器和解碼器

把視頻或者音頻按照編碼格式,編碼成特定文件格式需要編碼器的參與,不然每次開發重新寫代碼代價很高。

把特定文件格式解碼成特定的編碼格式數據,這個過程稱爲解碼,需要解碼器的存在。

解碼器和編碼器都有開源的或者收費的工具庫,極大方便了開發者。

5. FPS 幀率

我們讀初中物理時,大概瞭解過電影畫面一秒鐘 24 幀,其實對應的就是 24 fps,frame per second,有些手機有高速攝像的功能,原理就是能夠 1 秒鐘拍攝 960 張圖片,然後用正常的速度放映出來,所以細節比較多。

fps 越高,細節越好,體驗也越好,但是文件容量也越高。

 

不同的文件格式如 mp4、avi、mkv 等等,它們存放 打包數據的方式不一樣,文件內部文件編碼方式也可能不一樣。

6.VideoWriter

用 OpenCV 保存視頻非常簡單,通過調用它的 VideoWriter類。詳細函數格式 VideoWriter(filename, fourcc, fps, frameSize[, isColor])。

  1. 第一個參數是要保存的文件的路徑
  2. fourcc 指定編碼器
  3. fps 要保存的視頻的幀率
  4. frameSize 要保存的文件的畫面尺寸
  5. isColor 指示是黑白畫面還是彩色的畫面

7.一些其他細節

通過攝像頭捕捉讀入視頻,獲取第一個攝像頭cv2.VideoCapture(0),如果有多個攝像頭可以修改參數,比如改成1是第二個攝像頭。

視頻編解碼器VideoWriter_fourcc,fourcc意思爲四字符代碼(Four-Character-Codes),顧名思義該編碼由4個字符組成,下面是VideoWriter_fourcc對象的一些常用參數,注意:字符順序不能弄混。

  • cv2.VideoWriter_fourcc('I', '4', '2', '0'),該參數是YUV編碼類型,文件名後綴爲.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', '1'),該參數是Flash視頻,文件名後綴爲.flv

fourcc 本身是一個 32 位的無符號數值,用 4 個字母表示採用的編碼器。 常用的有 “DIVX"、”MJPG"、“XVID”、“X264"。

推薦使用 ”XVID", cv2.VideoWriter_fourcc(*'XVID'),但一般依據你的電腦環境安裝了哪些編碼器。

8.代碼示例

#!/usr/bin/env python 
# -*- coding: utf-8 -*-
# @Time    : 2020/3/29 10:11
# @Author  : King110108
# @File    : webcame.py
# @Description: 
# @IDE     : PyCharm

import cv2

cap = cv2.VideoCapture(0) #讀取攝像頭,0爲攝像頭索引,當有多個攝像頭時,從0開始編號
fourcc = cv2.VideoWriter_fourcc(*'XVID') #創建視頻流寫入對象,VideoWriter_fourcc爲視頻編解碼器
#fourcc意爲四字符代碼(Four-Character Codes),顧名思義,該編碼由四個字符組成,下面是VideoWriter_fourcc對象一些常用的參數,注意:字符順序不能弄混
# cv2.VideoWriter_fourcc('I', '4', '2', '0'),該參數是YUV編碼類型,文件名後綴爲.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', '1'),該參數是Flash視頻,文件名後綴爲.flv

out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480)) #設置視頻參數, 20爲幀播放速率,640x480是視頻輸出窗口大小

while True:
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #轉爲灰度
    out.write(frame) #寫入視頻
    cv2.imshow('frame', frame) #彩色顯示
    cv2.imshow('gray', gray) #灰度顯示

    if cv2.waitKey(1) & 0xFF == ord('q'):  #按q退出程序
        break

cap.release()
out.release()
cv2.destroyAllWindows()

這段代碼的目的就是獲取攝像頭的視頻流,然後保存到本地,幀率是 20fps,尺寸是 640x480.

需要注意的是在 VideoWriter 中指定的尺寸要和 write() 中寫進去的一樣,不然視頻會存儲失敗的。

如果需要讀取視頻文件,那麼就將 VideoCapture 指定文件路徑。

如果,將圖片序列合成爲視頻文件,其實原理也一樣,一張一張讀取,然後寫到 VideoWriter 當中去。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章