1. 程式人生 > 其它 >Opencv處理視訊序列

Opencv處理視訊序列

技術標籤:opencvffmpeg計算機視覺

一、什麼是FOURCC

FOURCC是“four character code”的縮寫,也稱為4CC。用於媒體檔案中的視訊編解碼器、壓縮格式、顏色或畫素格式的識別符號。一個字元編碼佔用一個位元組也就是8位的儲存空間,因此一個FOURCC佔用4位元組。FOURCC中的四個字元通常都是用ASCII字元編碼,以方便交流。

AVI檔案是最廣泛使用的,或者說是第一種廣泛使用的媒體檔案格式,它使用FOURCC識別符號作為編解碼器用於壓縮檔案中的各種視訊/音訊流。其他比較著名的FOURCC包括DIVX、XVID、H264、DX50。但這些只是數百個在使用的FOURCC的一小部分。

視訊的大小直接影響視訊分析的實時性,而視訊檔案的大小影響因素有時長、格式、幀率(FPS)以及解析度等,因此需要選擇合適的格式,或者做一些壓縮處理。部分CV_FOURCC測試如下:
在這裡插入圖片描述

二、視訊壓縮

ffmpeg是格式轉化和壓縮的工具,使用命令列進行轉化。參考文件 http://wiki.webmproject.org/ffmpeg。
測試如下:

ffmpeg -i test_mjpg.avi -threads 4 -vcodec libvpx-vp9 -cpu-used -8 -crf 10 -qmax 60 -deadline realtime test.webm

實測:19M壓縮為1.6M

三、圖片序列轉視訊

VideoWriter(const string& filename, int fourcc, double fps,
			Size frameSize, bool isColor=true);

各引數含義如下:

  • filename: 輸出視訊檔案的名稱
  • fourcc:four character code,四個字元用來表示壓縮幀的編解碼
  • fps:幀率
  • frameSize:每幀圖片的大小
  • isColor: 預設非零,編碼器將得到彩色幀並進行編碼

第二個引數OpenCV提供的格式是未經過壓縮的,目前支援的格式如下

  • 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
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(){
    Mat src=imread("/home/xxx/cam0/0.png",1);
    char image_name[100];
    int isColor = 1;
    int fps = 10;
    int frameWidth = src.cols;
    int frameHeight = src.rows;

    VideoWriter writer("test.avi", CV_FOURCC('M', 'J', 'P', 'G'), fps, Size(frameWidth, frameHeight), 0);
    
    cout << "info:" << endl
         << "test.avi" << endl
         << "Size:" << frameWidth << "*" << frameHeight << endl
         << "fps:" << fps << endl;
    
    for (int i = 0; i < 1000; i++)
    {
        sprintf(image_name, "/home/xxx/cam0/%d.png",i);
        cout<<image_name<<endl;
        src = imread(image_name, 1);

        if (src.empty())
        {
            cout<<"全部影象載入完成!"<<endl;
            break;
        }
        writer<<src;
		if (cvWaitKey(5) > 0)                  
			break;
    }

    writer.release();
    destroyAllWindows();

    return 0;
}

參考其他部落格:
https://www.fourcc.org/fourcc.php
https://brucedone.com/archives/1194
https://blog.csdn.net/cow_boy001/article/details/8294403?locationNum=1&fps=1