OpenCV基礎教程——視頻的讀取與寫入(超詳細+附代碼)

上一篇文章介紹了OpenCV對於圖像的處理方法,然而目前對視頻的處理分析越來越成爲計算機視覺的主流,視頻中包含的信息量要遠遠大於圖片,而本質上視頻是由一幀幀的圖像組成,所以視頻處理最終還是要歸結於圖像處理,但在視頻處理中,有更多的時間維的信息可以利用。本文主要介紹OpenCV在處理視頻時的一些基本函數


1、視頻的讀取(cv::VIdeoCpature)

視頻讀取,主要利用VideoCapture類下的方法打開視頻並獲取視頻中的幀,其操作有很多,這裏只提及最普遍的用法

具體可見:https://docs.opencv.org/3.1.0/d8/dfe/classcv_1_1VideoCapture.html

1.1使用構造函數獲取視頻文件

//在該構造函數中,輸入正確的視頻文件的文件路徑即可,OpenCV會打開對應的視頻文件

cv::VideoCapture::VideoCapture(const string&    filename);

打開視頻文件有兩種方法

//方法一
VideoCapture cap("E:/myFile/video/ty.mp4");//獲取E:/myFile/video路徑下的ty.mp4視頻文件
//方法二
VideoCapture cap;
cap.open("E:/myFile/video/ty.mp4");//使用open方法

//在該構造函數中,輸入攝像頭ID,則可打開對應的攝像頭,默認攝像頭爲0

cv::VideoCapture::VideoCapture(int device);

VideoCapture cap(0);//讀取默認攝像頭

1.2驗證視頻是否讀入成功

若成功讀取視頻文件則放回True,否則返回False

if (!cap.isOpened())
{
    cout << "無法打開視頻文件!" << endl;
    return -1;
}

1.3獲取視頻幀

獲取視頻幀有以下多種方法

Mat frame;
//方法一
capture.read(frame);
//方法二
capture.grab();
capture.retrieve(frame);
//方法三
capture>>frame;

1.4獲取視頻的參數

一個視頻有很多參數,如:幀率、總幀數、尺寸、格式等,VideoCapture的get方法可以獲取大量的這些參數

參數表如下表所示

             參數

                      對應宏                                                    說明
VideoCapture.get(0) CV_CAP_PROP_POS_MSEC 視頻文件的當前位置(播放)以毫秒爲單位
VideoCapture.get(1) CV_CAP_PROP_POS_FRAMES 基於以0開始的被捕獲或解碼的幀索引
VideoCapture.get(2) CV_CAP_PROP_POS_AVI_RATIO 視頻文件的相對位置(播放):0=電影開始,1=影片的結尾
VideoCapture.get(3) CV_CAP_PROP_FRAME_WIDTH 在視頻流的幀的寬度
VideoCapture.get(4) CV_CAP_PROP_FRAME_HEIGHT 在視頻流的幀的高度
VideoCapture.get(5) CV_CAP_PROP_FPS 幀速率/幀數/fps
VideoCapture.get(6) CV_CAP_PROP_FOURCC 編解碼的4字-字符代碼
VideoCapture.get(7) CV_CAP_PROP_FRAME_COUNT 視頻文件中的幀數
VideoCapture.get(8) CV_CAP_PROP_FORMAT 返回對象的格式
VideoCapture.get(9) CV_CAP_PROP_MODE 返回後端特定的值,該值指示當前捕獲模式
VideoCapture.get(10) CV_CAP_PROP_BRIGHTNESS 圖像的亮度(僅適用於照相機)
VideoCapture.get(11) CV_CAP_PROP_CONTRAST 圖像的對比度(僅適用於照相機)
VideoCapture.get(12) CV_CAP_PROP_SATURATION 圖像的飽和度(僅適用於照相機)
VideoCapture.get(13) CV_CAP_PROP_HUE 色調圖像(僅適用於照相機)
VideoCapture.get(14) CV_CAP_PROP_GAIN 圖像增益(僅適用於照相機)(Gain在攝影中表示白平衡提升)
VideoCapture.get(15) CV_CAP_PROP_EXPOSURE 曝光(僅適用於照相機)
VideoCapture.get(16) CV_CAP_PROP_CONVERT_RGB 指示是否應將圖像轉換爲RGB布爾標誌
VideoCapture.get(17) CV_CAP_PROP_WHITE_BALANCE × 暫時不支持
VideoCapture.get(18) CV_CAP_PROP_RECTIFICATION 立體攝像機的矯正標註(目前只有DC1394 v.2.x後端支持這個功能)

示例如下圖所示

1.5設置視頻幀的讀取位置

VideoCapture類的set方法可以允許我們取出視頻中某個位置的幀

它有一些參數,可以按時間,也可以按幀號,還可以按視頻長短的比例

//第100幀
double position=100.0;
capture.set(CV_CAP_PROP_POS_FRAMES,position);
//第1e6毫秒
double position=1e6;
capture.set(CV_CAP_PROP_POS_MSEC,position);
//視頻1/2位置
double position=0.5;
capture.set(CV_CAP_PROP_POS_AVI_RATIO,position);

同時set方法還可以設置視頻的幀率、亮度

2、視頻的寫入(cv::VIdeoWriter)

視頻的寫入與讀取類似,使用VideoWriter類來實現,這個類有幾個方法,除了構造函數外,提供了open、IsOpen、write、和重載操作符<<

cv::VideoWriter(const string& path,int fourcc,double fps, Size framesize, bool isColor=true)

  • 第一個參數表示保存的文件路徑和文件名
  • 第二個參數表示編碼格式
  • 第三個參數表示幀率
  • 第四個參數表示視頻尺寸大小
  • 第五個參數表示視頻圖像類型(true彩色,false灰度)

需要注意的是fourcc的常用格式有

  • CV_FOURCC('P','I','M','1') = MPEG-1 codec
  • CV_FOURCC('M','J','P','G') = motion-jpeg codec
  • CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec
  • CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec
  • CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec
  • CV_FOURCC('U', '2', '6', '3') = H263 codec
  • CV_FOURCC('I', '2', '6', '3') = H263I codec
  • CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec

3、視頻讀寫程序示例

視頻讀取

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    VideoCapture cap("E:/myFile/video/ty.mp4");
    Mat frame;
    if (!cap.isOpened())
    {
        cout << "無法打開視頻文件!" << endl;
        return -1;
    }

    namedWindow("video", CV_WINDOW_AUTOSIZE);
    while (cap.read(frame))
    {
        imshow("video", frame);
        waitKey(10);
    }
    cap.release();

    waitKey(0);
    return 0;
}

視頻寫入

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    VideoCapture cap("E:/myFile/video/ty.mp4");
    Mat frame, gray;
    if (!cap.isOpened())
    {
        cout << "無法打開視頻文件!" << endl;
        return -1;
    }

    //獲取視頻幀的長和寬
    Size size = Size(cap.get(CV_CAP_PROP_FRAME_WIDTH), cap.get(CV_CAP_PROP_FRAME_HEIGHT));
    VideoWriter writer("E:/myFile/video/ty_g.mp4", CV_FOURCC('M', 'J', 'P', 'G'), 24, size, true);

    namedWindow("video", CV_WINDOW_AUTOSIZE);
    while (cap.read(frame))
    {
        //imshow("video", frame);
        //轉換爲黑白圖像
        cvtColor(frame, gray, COLOR_BGR2GRAY);
        //二值化處理
        threshold(gray, gray, 0, 255, THRESH_BINARY | THRESH_OTSU);
        cvtColor(gray, gray, COLOR_GRAY2BGR);
        imshow("video", gray);
        writer.write(gray);
        waitKey(10);
	}

    waitKey(0);
    cap.release();
    return 0;
}

歡迎大家補充學習!!!

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