天天看點

基礎學習筆記之opencv(6):實作将圖檔生成視訊

    在做實驗的過程中,難免會讀視訊中的圖檔用來處理,相反将處理好的圖檔又整理輸出為一個視訊檔案也是很常用的。下面就來講講基于opencv的C++版本中圖檔輸出視訊是怎麼實作的。

    本次試驗的資料為搖擺的樹枝樹葉圖檔,Waving Trees,其來源網址為: http://research.microsoft.com/en-us/um/people/jckrumm/WallFlower/TestImages.ht

    該資料全由bmp圖檔組成。

      本次試驗的工程環境為:opencv2.3.1+vs2010

    實驗功能:将多張bmp彩色圖檔生成一個avi格式的灰階視訊檔案。

      在試驗過程中,需要注意一下幾點:

  1.輸出視訊檔案命名的處理和視訊幀率的選擇

  2.輸出視訊檔案格式的選擇,好像opencv支援2種,一種是MIP1,和MJPG。但是試驗過程中發現如果選擇MIP1不僅輸出視訊品質非常差,且幀率不能控制。

  3.關于視訊輸出是否為彩色問題見代碼注釋部分。

  下面是工程代碼:

// generate_vedio.cpp : 定義控制台應用程式的入口點。
//

#include "stdafx.h"

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, unsigned char* argv[])
{
    String str_name="WavingTrees/b00";
    char str[4];

    Mat img_src,img_dst;
    vector<Mat> img_gray;

    img_src=imread("WavingTrees/b00000.bmp");

    //使用VideoWriter時,如果需要寫視訊的檔案不存在,則建立一個,如果存在,則必須是合法的視訊檔案,否則下面的語句會報錯
    //如果選擇PIM1格式時,輸出視訊的幀率不能手動選擇,且輸出視訊效果非常糟糕
    //VideoWriter output_src("demo_src.avi",CV_FOURCC(\'P\',\'I\',\'M\',\'1\'),2,img.size(),1);//輸出彩色視訊
    //VideoWriter output_dst("demo_dst.avi",CV_FOURCC(\'P\',\'I\',\'M\',\'1\'),25,img.size(),0);//輸出灰階視訊

    //當用MJPG格式時,可以選擇輸出的幀率,且視訊輸出的效果也要好很多,是以一般采用這種格式輸出
    //最後一個參數isColor如果為非0的話,則表示輸出3通道彩色視訊,否則當isColor=0時輸出為單通道黑白灰階視訊
    //不過此時當放入視訊的圖檔為單通道圖檔時,輸出的視訊雖然是黑白灰階的,但是确同時有3幅圖出現,即寬度壓縮了3倍
    VideoWriter output_src("demo_src.avi",CV_FOURCC(\'M\',\'J\',\'P\',\'G\'),10,img_src.size(),1);//輸出灰階視訊
    VideoWriter output_dst("demo_dst.avi",CV_FOURCC(\'M\',\'J\',\'P\',\'G\'),10,img_src.size(),1);//輸出灰階視訊

    int i=-1;


    namedWindow("src",WINDOW_AUTOSIZE);
    while(1)
    {
        i++;

        /****圖檔名字讀取前的處理****/
        _itoa_s(i,str,10);
        if(i<10)
            str_name+="00";
        else if(i<100)
            str_name+="0";
        str_name+=str;
        str_name+=".bmp";
        if(256==i)
            return 0;

        /****輸出原彩色視訊****/
        img_src=imread(str_name);
        if(img_src.empty())
            return 0;
        output_src<<img_src;

        /****輸出目标灰色視訊****/
        //這裡用split函數的目的是為了給vector<Mat>型變量确定邊界,如果沒有此語句,
        //則下面使用img_gray[1]就會認為是錯誤的
        split(img_src,img_gray);
        cvtColor(img_src,img_gray[1],CV_BGR2GRAY);//這樣輸出的是彩色視訊
        //如果其它通道賦0的話,不是真正意義上的黑白灰階圖,而是背景為藍色的灰階圖
    //    img_gray[0]=img_gray[2]=Mat::zeros(img_src.size(),img_gray[1].type());
        img_gray[0]=img_gray[2]=img_gray[1];//這樣指派才是真正意義上的黑白灰階圖
        merge(img_gray,img_dst);

        //但這樣輸出的雖然是灰階視訊,可是一副圖像中包含了3個一樣圖,即圖像寬度被壓縮了3倍,why?
        //且此時不能輸出3通道的圖檔,否則生成的視訊不能播放
        output_dst<<img_dst;
    //    output_dst<<img;

        imshow("src",img_src);

        /****延時處理****/
        char c=(char)waitKey(10);
        if(27==c)
            return 0;

        str_name="WavingTrees/b00";
    }



    return 0;
}      
基礎學習筆記之opencv(6):實作将圖檔生成視訊