OpenCV C++簡單的視頻讀取和保存入門

      網友投稿 3043 2025-03-31

      1 視頻編碼概述

      根據百度百科的定義,視頻編碼本質上就是一種視頻的壓縮技術,不同的視頻編碼方式代表不同的壓縮方式,其壓縮率和視頻質量都存在一定的差異。不同編碼的視頻往往需要通過工具進行視頻格式轉換。目前來說,視頻流傳輸中最為重要的編解碼標準有:國際電聯的H.263、H.264和H.265;運動靜止圖像專家組的M-JPEG;運動圖像專家組的MPEG系列標準。

      視頻的本質可以看作是連續的圖像序列,圖像序列中的每一個圖像被稱為幀,換句話說:一幀就是一幅圖像。由于人眼的視覺暫留效應,當幀序列以一定的速率播放時,比如1秒24幀,那么往我們看到的就是連續的動作比較流暢的視頻。由于連續的幀之間相似性極高,為便于儲存傳輸,需要對原始的視頻進行編碼壓縮,以去除空間、時間維度的冗余。

      2 重要的視頻編碼概述

      視頻編碼方式非常的多,但是基于標準的視頻編碼系列可以總結如下幾類 :(1)MPEG系列,由ISO(國際標準組織機構)下屬的運動圖象專家組開發的視頻編碼方案,其中主要是Mpeg1(VCD)、Mpeg2(DVD)、Mpeg4(如divx,xvid等)、Mpeg4 AVC。主要應用于視頻存儲、廣播電視、互聯網或無線網絡的流媒體等。(2)H.26X系列,側重網絡傳輸,主要應用于實時視頻通信領域,如可視電話、實時視頻會議、視頻監控、流媒體、多媒體視頻和Internet視頻及多媒體等;H.262標準等同于 MPEG-2的視頻編碼標準,而H.264/AVC標準則被納入 MPEG-4的第10部分。 如今廣泛使用的 H.264 視頻壓縮標準(如.mp4文件)可以基于H5進行視頻播放,目前還有一種更高的壓縮率以及更高質量的編碼標準H.265/HEVC標準。H.265的壓縮有了顯著提高,一樣質量的編碼視頻能節省40%至50%的碼流,還提高了并行機制。

      3 OpenCV 視頻入門

      首先用Visual Studio 工具新建一個C++項目,并進行相關配置,具體可以參考上一篇博文《OpenCV 4 C++環境快速搭建》,這里不再贅述。下面給出一個視頻操作的核心代碼,具體如下所示:

      #include #include #include #include #include using namespace cv; using namespace std; int main(int, char**) { //Matrix 對象,存儲圖像的數值,處理圖像而引入的一個封裝類 Mat src; //默認攝像頭 VideoCapture cap(0); // 檢查攝像頭是否打開 if (!cap.isOpened()) { cerr << "Unable to open camera\n"; return -1; } //獲取幀的寬和高,以及每秒幀數 cout << "Frame width: " << cap.get(CAP_PROP_FRAME_WIDTH) << endl; cout << "Frame height: " << cap.get(CAP_PROP_FRAME_HEIGHT) << endl; cout << "FPS: " << cap.get(CAP_PROP_FPS) << endl; // 0 //讀取 cap >> src; // 檢測讀取視頻情況 if (src.empty()) { cerr << "blank frame grabbed\n"; return -1; } //是否是彩色的 bool isColor = (src.type() == CV_8UC3); //VideoWriter可以將圖像生成視頻 VideoWriter writer; double fps = 24.0; if (cap.get(CAP_PROP_FPS) > 0) { fps = cap.get(CAP_PROP_FPS); } // !!! fourcc 編碼和 視頻擴展名,需要匹配,而且不同平臺是不同的 /////////////////////////////////////////////////////////////// int codec = VideoWriter::fourcc('X', 'V', 'I', 'D'); string filename = "./live_xvid.mp4"; /////////////////////////////////////////////////////////////// writer.open(filename, codec, fps, src.size(), isColor); //檢查是否可以正常打開文件 if (!writer.isOpened()) { cerr << "Could not open the output video file for write\n"; return -1; } cout << "###################### " << endl; for (;;) { //檢查是否讀取正常 if (!cap.read(src)) { cerr << " blank frame grabbed\n"; break; } //將幀圖像寫入視頻文件 writer.write(src); //顯示標題為Live的窗口來顯示視頻 imshow("Live", src); //監聽鍵盤任意鍵,退出 if (waitKey(5) >= 0) break; } return 0; }

      首先,需要用 include 引入相關的頭文件,然后用 using namespace cv 引入 opencv命令空間,int main(int, char**) 是函數入口,Mat src中的Mat是一個Matrix 對象,存儲圖像的數值,處理圖像而引入的一個封裝類。VideoCapture cap(0) 從默認攝像頭進行捕獲,cap.isOpened()可以判斷是否可以正常捕獲視頻,cap.get(CAP_PROP_FRAME_WIDTH)和cap.get(CAP_PROP_FRAME_HEIGHT)可以獲取獲取幀的寬和高。

      cap >> src 則讀取視頻數據到Mat src中,VideoWriter可以將圖像生成視頻,這是opencv圖像操作的核心類,int codec = VideoWriter::fourcc('X', 'V', 'I', 'D');則給出了視頻的編碼方案Xvid,它是一個開放源代碼的MPEG-4視頻編解碼器,它是基于OpenDivX而編寫的,同時它是世界上最常用的視頻編碼解碼器(codec),它的總體表現非常的好。還有一種DivX視頻編碼,支持MPEG-4, H.264和H.265標準的視頻,分辨率可高達4K超高清。

      注意:XviD編碼的的視頻文件擴展名可以是AVI、MKV、MP4等。需要說明的是,僅從擴展名并不能看出這個視頻的編碼格式。

      那么,opencv能否支持H.264呢,比較將設置如下所示:

      int codec = VideoWriter::fourcc('H', '2', '6', '4'); string filename = "./live_h264.mp4";

      在Windows平臺上運行此代碼,則拋出如下信息:

      Failed to load OpenH264 library : openh264 - 1.8.0 - win64.dll Please check environment and /or download library : https://github.com/cisco/openh264/releases

      其中讓我們使用OpenH264,從 https://github.com/cisco/openh264/releases 上下載 openh264-1.8.0-win64.dll ,放于 文件源碼目錄中即可加載。再次運行,則拋出如下信息:

      PluginBackend::initWriterAPI Video I / O: plugin is ready to use 'FFmpeg OpenCV Video I/O Writer plugin' OpenCV : FFMPEG : tag 0x34363248 / 'H264' is not supported with codec id 27 and format 'mp4 / MP4 (MPEG-4 Part 14)' OpenCV : FFMPEG : fallback to use tag 0x31637661 / 'avc1' OpenH264 Video Codec provided by Cisco Systems, Inc. Writing videofile : . / live.mp4 Press any key to terminate

      其中正確加載了 openh264-1.8.0-win64.dll ,顯示OpenH264 Video Codec 相關字樣。但是提示了 'H264' is not supported with codec id 27 and format 'mp4 / MP4 (MPEG-4 Part 14)' 。說明H264和mp4文件不兼容,系統回退到OpenH264提供的 AVC1編碼,因此修改編碼如下即可:

      int codec = VideoWriter::fourcc('a', 'v', 'c', '1'); //avc1 //openh264 string filename = "./live.mp4";

      我嘗試了另外一種編碼,也成功了,代碼如下:

      int codec = VideoWriter::fourcc('X', '2', '6', '4'); string filename = "./live_x264.mkv";

      如何查看視頻的編碼信息呢,可以按照 ffmpeg 工具,其中一個組件為 ffprobe ,下面給出命令:

      C:\ffmpeg\bin>ffprobe.exe live_x264.mkv

      輸出如下信息:

      Metadata: ENCODER : Lavf58.76.100 Duration: 00:00:46.04, start: 0.000000, bitrate: 3681 kb/s Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 640x480, 24 fps, 24 tbr, 1k tbn, 2k tbc (default) Metadata: DURATION : 00:00:46.042000000

      其中的 h264 (Constrained Baseline), yuv420p(progressive), 640x480, 24 fps 則表示h264編碼,視頻寬高為640x480,幀數為24 。下面給出AVC1編碼生成的視頻信息:

      OpenCV C++簡單的視頻讀取和保存入門

      Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'live.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.76.100 Duration: 00:01:13.75, start: 0.000000, bitrate: 1847 kb/s Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x480, 1847 kb/s, 12 fps, 12 tbr, 12288 tbn, 24576 tbc (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0]

      其中顯示的是 h264 (Constrained Baseline) (avc1 / 0x31637661)? 。下面給出另外的編碼及輸出信息:

      int codec = VideoWriter::fourcc('M', 'J', 'P', 'G'); string filename = "./live_mjpg.avi"; ####################################### Input #0, avi, from 'live_mjpg.avi': Metadata: software : Lavf58.76.100 Duration: 00:00:11.08, start: 0.000000, bitrate: 7185 kb/s Stream #0:0: Video: mjpeg (Baseline) (MJPG / 0x47504A4D), yuvj420p(pc, bt470bg/unknown/unknown), 640x480, 7203 kb/s, 24 fps, 24 tbr, 24 tbn, 24 tbc

      說明此時是mjpeg (Baseline) (MJPG / 0x47504A4D) 編碼。下面給出本文示例中的編碼及輸出信息:

      int codec = VideoWriter::fourcc('X', 'V', 'I', 'D'); string filename = "./live_xvid.mp4"; ############################# Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'live_xvid.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2mp41 encoder : Lavf58.76.100 Duration: 00:00:05.38, start: 0.000000, bitrate: 5824 kb/s Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 5822 kb/s, 24 fps, 24 tbr, 12288 tbn, 24 tbc (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0]

      由此可見,XVID編碼使用的是 mpeg4 (Simple Profile) (mp4v / 0x7634706D) 。

      OpenCV Visual Studio 視頻

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:什么插入圖片時候,圖片會變沒了? ?正常插入時候 圖是不能調整,或者調整大小后,點圖片就變成空白,
      下一篇:對文檔進行了修改,目錄中為何不顯示該項修改(生成目錄不對怎么修改)
      相關文章
      久久夜色精品国产嚕嚕亚洲av| 亚洲国产黄在线观看| 亚洲国产精品视频| 亚洲成a人无码亚洲成www牛牛| 亚洲不卡中文字幕| 亚洲丝袜中文字幕| 国产亚洲精品影视在线| 亚洲人成人网毛片在线播放| 在线观看亚洲AV日韩AV| 在线观看亚洲AV日韩AV| 亚洲精品成a人在线观看☆| 亚洲成AV人片在WWW| 亚洲欧美成人综合久久久| 亚洲人成色777777老人头| 亚洲国产精品成人AV在线| 豆国产96在线|亚洲| 亚洲伊人久久综合影院| 区久久AAA片69亚洲| 亚洲国产精品无码中文字| 亚洲国产精品久久久久婷婷软件| 亚洲精品国产成人99久久| 亚洲美女免费视频| 亚洲娇小性色xxxx| 亚洲国产AV无码一区二区三区 | 亚洲成av人片在www鸭子| 日韩亚洲翔田千里在线| 亚洲日本在线观看视频| 亚洲精品制服丝袜四区| 亚洲无线电影官网| 亚洲人成网网址在线看| 亚洲成在人线aⅴ免费毛片| 亚洲国产成人精品女人久久久 | 亚洲丝袜中文字幕| 亚洲精品宾馆在线精品酒店| 亚洲AV无码一区二区三区在线观看 | 久久久久亚洲av无码专区导航| 亚洲精品国产专区91在线| 亚洲Av高清一区二区三区| 亚洲国产区男人本色| 亚洲色欲久久久久综合网| 亚洲成AV人在线播放无码|