OpenCV讀取AVI文件

問題:爲什麼我的電腦支持AVI或者能夠播出AVI,但爲什麼使用cvCreateFileCapture函數總返回NULL呢?
答案:儘管是AVI文件,但也可能使用了某種codec,例如:MJPEG Decompressor。 需要把它轉換OpenCV支持的AVI文件. OpenCV支持的AVI如下:

Container

FourCC

Name

Description

AVI

'DIB '

RGB(A)

Uncompressed RGB, 24 or 32 bit

AVI

'I420'

RAW I420

Uncompressed YUV, 4:2:0 chroma subsampled

AVI

'IYUV'

RAW I420

identical to I420


轉換格式解決方法:
解決方法1下載mencoder.exe, 在window命令行下使用:
 mencoder in.avi -ovc raw -vf format=i420 -o out.avi
(注:我測試了這個方法,沒有成功,原因不詳,希望有朋友們能夠詳細討論一下。)

解決方法2:下載VitualDub, 我使用1.9.4版本
a. File->Open Video File;
b. Video->Filters->Add->Convert format; 選擇4:2:0 Planar YCbCr (YV12)或者 32-Bit RGB。
c. Save as AVI. 保存完畢。
(注:成功使用。)

 

 

1、用opencv打開AVI格式文件
我的用的VISTA系統+VC6.0+opencv1.0
注意:使用XP系統也一樣。
(1)首先要安裝opencv1.0 。詳細安裝方法見http://www.opencv.org.cn/index.php/VC6下安裝與配置
(2)安裝XviD 解碼器。安裝方法見
http://www.opencv.org.cn/index.php/�% ... 2述
這一步很重要,如果不安裝XVID解碼器,在後來打開或保存視頻時可能會失敗。
(3)打開AVI文件的代碼如下:

代碼:

#include <string>
using namespace std;
int main()
{
   IplImage *frame = NULL;
   CvCapture *capture = NULL;
  capture = cvCaptureFromAVI("test.AVI");
    frame = cvQueryFrame(capture);
   cvNamedWindow("frame");
   while(frame){
      cvShowImage("frame", frame);
      cvWaitKey(20);
      cout << "Frame Grabbed." << endl;
      frame = cvQueryFrame(capture);
   }
   return 0;
}


找一個AVI視頻,把名字改爲“test”,放入工程中,運行程序便可打開視頻文件。
2、用攝像頭讀入視頻並保存爲AVI格式文件
我用筆記本帶的攝像頭調試運行成功,特別注意創建視頻文件時,要使用CV_FOURCC('X', 'V', 'I', 'D'),其他格式不一定能成功。代碼如下:
代碼: 全選
#include "cv.h"
#include "highgui.h"
#include <ctype.h>
#include <stdio.h>
int main( int argc, char** argv )
{
    IplImage* img = 0;
   
    int nFrames = 50;
    CvCapture* capture = 0;
   CvVideoWriter *writer = 0;
   int isColor = 1;
    int fps = 25; // or 30
    int frameW = 640; //
    int frameH = 480; //
   
    if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
        capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
        if( !capture )
    {
        fprintf(stderr,"Could not initialize capturing...\n");
        return -1;
    }
       writer=cvCreateVideoWriter("out.avi",CV_FOURCC('X','V','I','D'),
    fps,cvSize(frameW,frameH),isColor);
//存儲視頻文件 CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0
for(int i=0;i<nFrames;i++)
{
cvGrabFrame(capture); // 抓取幀
img=cvRetrieveFrame(capture); // 恢復圖像
cvWriteFrame(writer,img); // 將幀添加入視頻文件
//顯示所抓視頻
cvNamedWindow("Live", CV_WINDOW_AUTOSIZE);//創建窗口
cvShowImage("Live", img);//顯示所抓視頻
cvWaitKey(20); // wait 20 ms
}
cvReleaseVideoWriter(&writer);
return 0;
}

3、用opencv打開MPEG格式文件和用攝像頭讀入並保存文件。
先解釋一下爲什麼要把AVI格式和MPEG格式分開介紹。
Opencv1.0原來並不支持MPEG格式,後來技術進步了,說只要更新一下庫就可以
(http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=1118&p=4118&hilit=read+mpeg&sid=cb83023cfdf58226e379e66929f0813a#p4118),但更新庫的方法是用英語介紹的,我到現在也沒讀明白。因此我鬱悶了很長一段時間,後來到國圖借了一本介紹opencv的書,還從網上下了<< learning opencv>>這本書,看到if you want to read a fi le encodedwith DIVX or MPG4 compression on a Windows machine, there are specific DLLs thatprovide the necessary resources to decode the video.也就是對於Windows、Linux和Mac OS三種系統下,需要分別安裝專門的DLLs才能支持讀寫MPEG文件。儘管知道了這一點,我還是沒能用opencv1.0實現打開MPEG文件。
於是,我下了最新版本的opencv2.0,我想最新版本應該不用再加什麼就可以用了吧,但是這個版本已經不支持VC6.0了,我就又裝載了VC 2008 Express。VC 2008 Express下安裝opencv2.0的方法見http://www.opencv.org.cn/index.php/VC_2008_Express下安裝OpenCV2.0
安裝完後我運行了一下程序,發現還是不行。在網上看見有人說要安裝ffdshow,於是我裝了這個,再運行一下果然可以了,我並不知道爲什麼,我也菜鳥,但能夠打開和保存MPEG文件就可以了,我要的就是這個結果。
打開MPEG文件的代碼如下:
代碼: 全選
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
   IplImage *frame = NULL;
   CvCapture *capture = NULL;
    capture = cvCreateFileCapture( "test.mp4" );
   frame = cvQueryFrame(capture);
   cvNamedWindow("frame");
   while(frame){
      cvShowImage("frame", frame);
      cvWaitKey(20);
      cout << "Frame Grabbed." << endl;
      frame = cvQueryFrame(capture);
   }
   return 0;
}

用攝像頭讀入視頻並保存爲MPEG格式文件代碼:
代碼: 全選
#include "cv.h"
#include "highgui.h"
#include <ctype.h>
#include <stdio.h>
int main( int argc, char** argv )
{
    IplImage* img = 0;
   
    int nFrames = 500;
    CvCapture* capture = 0;
   CvVideoWriter *writer = 0;
   int isColor = 1;
    int fps = 25; // or 30
    int frameW = 640; //
    int frameH = 480; //
   
    if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
        capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
      if( !capture )
    {
        fprintf(stderr,"Could not initialize capturing...\n");
        return -1;
    }
    writer=cvCreateVideoWriter("out.mp4",CV_FOURCC('D','I','V','X'),
       fps,cvSize(frameW,frameH),isColor);
//存儲視頻文件CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0
for(int i=0;i<nFrames;i++)
{
cvGrabFrame(capture); // 抓取幀
img=cvRetrieveFrame(capture); // 恢復圖像
cvWriteFrame(writer,img); // 將幀添加入視頻文件
//顯示所抓視頻
cvNamedWindow("Live", CV_WINDOW_AUTOSIZE);//創建窗口
cvShowImage("Live", img);//顯示所抓視頻
cvWaitKey(20); // wait 20 ms
}
cvReleaseVideoWriter(&writer);
return 0;
}

細心的朋友會發現,打開AVI和MPEG的代碼只改變了一句,保存時也是這樣。其實很多時候運行不出結果不是因爲代碼有錯,而是沒安裝必要的解碼器或者有些庫不支持某些函數。
4、關於argc, argv的問題
現在很多書上的程序例子都用main( int argc, char** argv )這種形式,這種程序有時候運行時會一閃而過,菜鳥們往往不知道該怎麼辦纔好。argc, argv有什麼意義,我沒有完全理解,大家可以百度一下。我說一下解決辦法。
現在假設有一個名爲“example”的工程在C盤根目錄下,其作用是打開一個AVI視頻文件。那麼首先用VC編譯一下,會看到工程裏多了一個名爲“debug”的文件,裏面包含了一個exe文件。把要打開的AVI視頻複製到debug文件裏。然後在運行輸入cmd,進入命令提示符窗口,輸入“CD C:\example\debug”,回車後輸入“example.exe test.avi”回車後就可看到運行結果。
注意:這裏假設exe文件名爲example,AVI文件名爲test,可根據實際情況改動。
Opencv是一個很好用的工具,但是初學者往往會遇到這樣那樣的困難,如果沒有高手指導,只能自己去查資料,這裏推薦兩個很有用的論壇:
一個就是本論壇,還有就是opencv-users http://n2.nabble.com/opencv-users-f1802565.html
最後,限於作者本人的水平,代碼來至網上和書上,本文僅供參考。
發佈了4 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章