こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

OpenCVでのcvCreateVideoWriterがうまくいきません

今回複数枚のbmp画像群を、その画像につけられた4桁の連番の順に順次AVIファイルのフレームとして格納して行き、最終的にひとつのAVIファイルを出力するというプログラムを書いていますが、OpenCVの関数である「cvCreateVideoWriter」で躓いています。

CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, double fps, CvSize frame_size, int is_color=1 );
という仕様で、第二引数に「-1」と入れることで、プログラム実行時ffmpegが自動的にどの動画像コーデックを使用するかを聞いてくるということだったのですが、そうしているにも関わらずコーデック選択画面は出ないどころか、出力された動画(avi)も再生できない破損したファイルとして出力されてしまいます。
何かコーデックをインストールする必要があるのか(動画のコーデックとして、Combined Community Codec Packをインストール済みです)、それともプログラム内にまずい箇所があるのか、わからなくてあせっています。どなたかわかる方いらっしゃいましたらご教授よろしくお願いいたします。

ソース↓↓

//---------------------------------------------------------
// bmp→aviコンバート
//---------------------------------------------------------
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1


#include <stdio.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>

#include <iostream>
using namespace std;

#include <fstream>


int main(int argc, char** argv)
{
//変数定義-----------------------------------------------
int key=NULL;
IplImage* img = NULL; //読み込んだ画像ファイル用
char* outputWindow = "Output"; //進行状況確認用ウィンドウ
CvVideoWriter* VideoWriter = NULL; //ビデオライタ
char* filename = "test.avi"; //出力ファイル名
double fps = 30; //ビデオのフレームレート
int i=0; //画像の連番カウント用
char ImageName[104]; //読み込む画像ファイル名
char NameTmp[100]; //上の連番なし
//--------------------------------------------------------



//元画像の読み込み&フレームへの埋込み----------------------------------------------
cout << "画像名を入力してください(4桁連番号省略)" << endl;
cin >> NameTmp;

sprintf(ImageName,"%s0000.bmp",NameTmp);

img = cvLoadImage(ImageName, CV_LOAD_IMAGE_GRAYSCALE);

//画像一枚目の読み込みの
if(img==NULL){
cout << ImageName << "の読み込み失敗" <<endl;
return 1;
}

//進行状況確認用ウィンドウ展開
cvNamedWindow(outputWindow, CV_WINDOW_AUTOSIZE);

//ログファイル展開
std::ofstream ofs;
ofs.open( "test.txt" );

ofs << "1枚目の画像展開成功" << std::endl;

//ビデオライタ展開
VideoWriter = cvCreateVideoWriter(filename, -1, fps, cvGetSize(img), 0);
ofs << "ビデオライタ展開" << std::endl;

while(img!=NULL){
//画像ファイルの連番に合わせて読み込むファイル名を変更
if(i<10){
sprintf(ImageName,"%s000%d.bmp",NameTmp,i);
}
else if(i<100){
sprintf(ImageName,"%s00%d.bmp",NameTmp,i);
}
else if(i<1000){
sprintf(ImageName,"%s0%d.bmp",NameTmp,i);
}
else{
sprintf(ImageName,"%s%d.bmp",NameTmp,i);
}

//進境状況をウィンドウに出力
cvShowImage(outputWindow, img);

//進行状況確認用。10ms待つ
key = cvWaitKey(10);

//ビデオ書き込み
cvWriteFrame(VideoWriter,img);
cout << ImageName << endl;
i+=1;
img = cvLoadImage(ImageName, CV_LOAD_IMAGE_GRAYSCALE); //次のフレーム画像の読み込み


ofs << i << "枚目の画像書き込み成功" << std::endl;

}

//ビデオ書き込み用メモリを開放
cvReleaseVideoWriter(&VideoWriter);

//ログファイルを閉じる
ofs.close();

//進行状況確認ウィンドウを閉じる
cvDestroyWindow(outputWindow);

return 0;
}

投稿日時 - 2009-07-02 11:15:00

QNo.5091955

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(1)

ANo.1

>第二引数に「-1」と入れることで、プログラム実行時ffmpegが自動的にどの動画像コーデックを使用するかを聞いてくるということだったのですが、

第二引数で、「-1」の代わりに、無圧縮コーデックの「CV_FOURCC('D','I','B',' ')」を指定して試してみて下さい。

第二引数に「-1」が使えるのは「一部の限られた実行環境のみ」で、質問者さんの実行環境で使える保障はどこにもありません。
(質問者さんの実行環境が明記されてないので「使える」とも「使えない」とも言えず、断言する事が出来ません)

投稿日時 - 2009-07-02 12:00:55

補足

回答ありがとうございます。
第二引数に「CV_FOURCC('D','I','B',' ')」を指定しましたが、以下のようなエラーが出てプログラムがストップしてしまいます。

Unsupported format or combination of formats (FFMPEG could not find a codec matching the given FOURCC code. Use fourcc=CV_FOURCC_DEFAULT for auto selection.)
in function CvVideoWriter_FFMPEG::open, d:\ArchivosDR\PruebasIMGS\PruebaV\OpenCV\otherlibs\highgui\cvcap_ffmpeg.cpp(1195)

一応一番下に記述してあるcvcap_ffmpeg.cppを見てみましたがさっぱりでした。;;

ちなみに実行環境は
OS:WindowsXP Professional Ver2002 ServicePack3
CPU:AMD Athron 64X2 Dual Core Processor 4000+ 2.10GHz
メモリ:2GB
コンパイラ:Visual C++ 2008 Express Edition
あと、ffopencv110.dllはYahoo Groupsの「OpenCV &middot; Open Source Computer Vision Library Community」内にアップしてある、リビルド済みの物に変えてあります。(Feb 2, 2009付の物)

投稿日時 - 2009-07-02 15:15:19

あなたにオススメの質問