opencv讀取視頻的過程是解碼:opencv讀取視頻文件

引言

深度解析OpenCV中VideoCapture對象背後的視頻編碼與解碼的第三方庫支持與速度之謎。

支持的第三編解碼庫與類型

我們都知道OpenCV中的VideoCapture視頻讀取是藉助其它的第三方庫來完成編碼與解碼的過程,當前支持的視頻解碼主要有:

mkv / mpeg2
mkv / h264
mkv / h265     
mkv / vp8        
mp4 / mpeg2 
mp4 / h264
mp4 / h265
avi / mpeg2
avi / h264       
avi / vp8

視頻編碼主要有:

mkv / mpeg2
mkv / h264
mkv / vp8
mp4 / h264     
avi / mpeg2
avi / h264
avi / vp8

我們最常見的OpenCV中讀取視頻文件的函數VideoCapture參數解釋如下:

cv::VideoCapture::VideoCapture(
         const String &        filename,
         int apiPreference = CAP_ANY
)

其中參數filename表示文件名稱,大家經常忽略第二個參數默認值為CAP_ANY,意思是系統自動檢測選擇。當讀取攝像頭或者IP視頻流的時候:

cv::VideoCapture::VideoCapture(
         int  index,
         int apiPreference = CAP_ANY
)

其中index表示相機的ID標識。

當讀取視頻文件時候第二個參數的可以設置為:

cv::CAP_FFMPEG
cv::CAP_INTEL_MFX

當讀取攝像頭或者視頻流時候,第二個參數可以設置為

cv::CAP_DSHOW // windows只支持
cv::CAP_MSMF
cv::CAP_V4L

如何查詢當前OpenCV版本支持哪些視頻編碼與解碼的第三方後端庫,可以通過下面的代碼完成:

std::vector<cv::VideoCaptureAPIs> vcs = cv::videoio_registry::getBackends();
for (auto item : vcs) {
    std::cout << "name:" << cv::videoio_registry::getBackendName(item) << std::endl;
}

運行結果如下:

深度解讀 OpenCV中的VideoCapture視頻讀取

我的版本是OpenVINO2021.02+OpenCV4.5.1的聯合編譯版本。所以支持GSTREAMER與INTEL_MFX兩個後端庫。視頻文件解碼採用FFMPEG與英特爾MFX庫時的對比演示代碼如下:

// cv::VideoCapture cap("D:/test.h264", cv::CAP_INTEL_MFX);
// cv::VideoCapture cap("D:/test.h264", cv::CAP_FFMPEG);
// cv::VideoCapture cap("D:/images/video/play_football.mp4", cv::CAP_FFMPEG);
cv::VideoCapture cap(0, cv::CAP_DSHOW);
cv::Mat frame;
cv::TickMeter tick;
int fps = cap.get(cv::CAP_PROP_FPS);
int h = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
int w = cap.get(cv::CAP_PROP_FRAME_WIDTH);
std::cout << "fps:" << fps << " heigh:" << h << " width:" << w << std::endl;
// cv::VideoWriter writer("D:/test.h264", cv::VideoWriter::fourcc('H', '2', '6', '4'), fps, cv::Size(w, h), true);
while (true)
{
    tick.start();
    bool ret = cap.read(frame);
    tick.stop();
    if (!ret) {
        break;
    }
    double res_fps = tick.getCounter() / tick.getTimeSec();
    std::cout << tick.getCounter() << " frames in " << tick.getTimeSec() << " sec ~ " << res_fps << " FPS" << " (total time: " << tick.getTimeSec() << " sec)" << std::endl;
    cv::imshow("input", frame);
    char c = cv::waitKey(1);
    // writer.write(frame);
    if (c == 27) {
        break;
    }
}
// writer.release();
cap.release();
return 0;

加速解碼

默認下載的OpenCV在Widnows下面只支持CAP_DSHOW這種方式實時視頻流解碼讀取,這種方式我測試下來實時性能沒有直接讀取視頻文件方式高效。單純的讀取我的電腦自帶攝像頭(酷睿i7 CPU第八代)速度大致只有35FPS左右,而我讀取視頻文件通過FFMPEG支持,可以輕鬆達到每秒220FPS左右。而且OpenCV中的FFMPEG是不支持硬件加速的版本,響應更好的響應視頻流水線操作就絕對不能這麼讀取,有什麼好的辦法?結合OpenCV有個技術線路可以提高視頻流的解碼速度,提升流水線作業效率。

方法:使用GSTREAMER支持方式

相比FFMPEG第三方庫,GSTREAMER支持多種後端,通過軟件支持硬件加速的方式解碼視頻與流水線解碼視頻操作,同時還支持異步操作,這一波操作之後,解碼速度會比最原始的OpenCV自動檢測得到的方法要快N多,官方實驗給出的數據如下:

深度解讀 OpenCV中的VideoCapture視頻讀取
深度解讀 OpenCV中的VideoCapture視頻讀取

實事證明的確可以加速很多!該方法只在ubuntu系統下驗證過,widnows系統下還沒有驗證過,官方說 in theory, can run~~~~作為技術人員看到這句話你懂的,就是坑很多,你自己看着辦

此外就是徹底放棄Windows的DSHOW,有錢買個加速卡,直接硬件解碼加速,這樣就無憂了。

為了讓大家更好得理解與使用OpenVINO框架,我特別整理了OpenVINO計算機視覺加速的學習路徑,圖示如下:

深度解讀 OpenCV中的VideoCapture視頻讀取

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/224229.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-09 14:37
下一篇 2024-12-09 14:37

相關推薦

發表回復

登錄後才能評論