OpenCV を使って avi 動画ファイルの再生
ここでは,OpenCV の C++ API を使用して avi 動画ファイルを再生する方法を示す。動画ファイルの連続再生と,任意のフレームを指定して表示する2つのプログラム例を紹介する。
【サイト内の OpenCV 関連ページ】
- OpenCV について [PDF] , [パワーポイント]
- OpenCV のインストール,画像表示を行う C++ プログラムの実行手順: 別ページ »で説明
- OpenCVとPythonを活用した画像・ビデオ処理プログラム: 別ページ »にまとめ
- OpenCV 4 の C/C++ プログラム: 別ページ »にまとめている.
【OpenCV の公式情報】
- OpenCV の公式ページ: https://opencv.org
- GitHub の OpenCV のページ: https://github.com/opencv/opencv/releases
◆プログラムの例 (avi 動画ファイル再生プログラム)
以下のプログラムは,指定した avi ファイルを読み込み,フレームレートに合わせて連続再生する。再生中は標準エラー出力にフレーム情報を表示し,ESC キーで終了する。動画が終端に達すると先頭に戻って再生を継続する。
#include<cv.h>
#include<highgui.h>
using namespace cv;
int main (int argc, char **argv)
{
double width; // 幅
double height; // 高さ
double fps; // フレームレート
double msec; // 現在位置
double index = -1; // フレームのインデックス
double ratio; // 相対位置
CvCapture *capture = NULL;
IplImage *frame = 0;
double prev_index;
int ch;
// 幅と高さの取得
capture = cvCaptureFromFile("/usr/local/share/OpenCV/samples/c/tree.avi");
width = cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH);
height = cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT);
fps = cvGetCaptureProperty (capture, CV_CAP_PROP_FPS);
namedWindow ("Video File", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
while (1) {
frame = cvQueryFrame (capture);
msec = cvGetCaptureProperty (capture, CV_CAP_PROP_POS_MSEC);
prev_index = index;
index = cvGetCaptureProperty (capture, CV_CAP_PROP_POS_FRAMES);
ratio = cvGetCaptureProperty (capture, CV_CAP_PROP_POS_AVI_RATIO);
cvShowImage ("Capture", frame);
ch = cvWaitKey ( 1000.0 / fps ); // 0 はディレイ時間 (ミリ秒単位)
if (ch == '\x1b') {
// ESC キー
break;
}
fprintf( stderr, "width = %f, height = %f, fps = %f, index = %f, msec = %f\n", width, height, fps, index, msec );
if ( prev_index == index ) {
cvSetCaptureProperty (capture, CV_CAP_PROP_POS_AVI_RATIO, 0.0);
}
}
cvReleaseCapture (&capture);
cvDestroyWindow ("Capture");
return 0;
}
◆プログラムの例 (avi 動画ファイルの任意のフレームを表示)
以下のプログラムは,指定した avi ファイルから任意のフレーム番号の画像を取得して表示する。フレーム番号を指定することで,動画内の特定の場面を静止画として確認できる。
#include<cv.h>
#include<highgui.h>
using namespace cv;
void capture (const char* avi_file_name, const int frame_num)
{
double width; // 幅
double height; // 高さ
double fps; // フレームレート
double msec; // 現在位置
double index = -1; // フレームのインデックス
double ratio; // 相対位置
CvCapture *capture = NULL;
IplImage *frame = 0;
// double prev_index;
// int ch;
// 幅と高さの取得
capture = cvCaptureFromFile( avi_file_name );
width = cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH);
height = cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT);
fps = cvGetCaptureProperty (capture, CV_CAP_PROP_FPS);
// ウインドウは開かない
namedWindow ("Video File", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
// 画像の取得
cvSetCaptureProperty (capture, CV_CAP_PROP_POS_FRAMES, frame_num);
frame = cvQueryFrame (capture);
// 情報の取得
msec = cvGetCaptureProperty (capture, CV_CAP_PROP_POS_MSEC);
index = cvGetCaptureProperty (capture, CV_CAP_PROP_POS_FRAMES);
ratio = cvGetCaptureProperty (capture, CV_CAP_PROP_POS_AVI_RATIO);
cvShowImage ("Capture", frame);
fprintf( stderr, "width = %f, height = %f, fps = %f, index = %f, msec = %f\n", width, height, fps, index, msec );
cvWaitKey( 10000.0 );
cvReleaseCapture (&capture);
cvDestroyWindow ("Capture");
return;
}
int main (int argc, char **argv)
{
capture( "/usr/local/share/OpenCV/samples/c/tree.avi", 60 );
return 0;
}
◆ Linux でのビルド手順例
以下のコマンドで上記プログラムをビルドする。OpenCV のインクルードパスとライブラリパスは環境に応じて変更すること。
g++ -o a.out hoge.cc -I/usr/local/include/opencv2 -I/usr/local/include/opencv -L/usr/local/lib -lopencv_photo -lopencv_imgproc -lopencv_highgui -lopencv_core
◆実行結果
上図は動画再生プログラムの実行画面である。