web-dev-qa-db-ja.com

OpenCVシーク機能/巻き戻し

C++でOpenCVを使用してシークおよび巻き戻し機能(ビデオ(.avi)用)を見つけて実装しようとしていますが、ファイル全体を一度調べて各画像を保存する以外に、それを行う方法を見つけることができません。他に方法はありますか?

どんな助けでも大歓迎です。よろしくお願いします!

22
Cenoc

CvSetCaptureProperty()を使用すると、ミリ秒単位または序数のフレーム番号でフレームを循環できます。

int cvSetCaptureProperty( CvCapture* capture, int property_id, double value );

property_idは、使用する必要のあるプロパティです。次のいずれかになります。

  1. CV_CAP_PROP_POS_MSEC-ファイルの先頭からのミリ秒単位の位置
  2. CV_CAP_PROP_POS_FRAMES-フレーム内の位置
  3. CV_CAP_PROP_POS_AVI_RATIO-相対単位での位置(0-ファイルの開始、1-ファイルの終了)
  4. CV_CAP_PROP_FRAME_WIDTH-ビデオストリームのフレームの幅(カメラのみ)
  5. CV_CAP_PROP_FRAME_HEIGHT-ビデオストリームのフレームの高さ(カメラのみ)
  6. CV_CAP_PROP_FPS-フレームレート(カメラのみ)
  7. CV_CAP_PROP_FOURCC-4文字のコーデックコード(カメラのみ)。

最初の2つはあなたの興味の対象です。

編集:詳細:)

上記の関数をさまざまなフレームインデックスで繰り返し呼び出すだけで、フレームを循環できます。

cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frameIndex);

例:

IplImage*  frame;
CvCapture* capture = cvCreateFileCapture("test.avi");

/* iterate through first 10 frames */
for (int i = 0; i < 10; i++)
{
   /* set pointer to frame index i */
   cvSetCaptureProperty(capture, CV_CAP_POS_FRAMES, i);

   /* capture the frame and do sth with it */
   frame = cvQueryFrame(capture);
}

ユーザーがボタンをクリックしてビデオを転送/巻き戻すたびに実行する同様のコードを配置できます。

C++メソッド(OpenCV 2以降)では、代わりに同じproperty_idとvalueでこのメソッドを使用します。

bool VideoCapture::set(int property_id, double value)
42
Adi

ファイル全体をIplImageの配列に読み込んでから、それを処理する必要があると思います。その理由は、cvQueryFrameは一方向のプロセスであり、一度に1つのフレームを順番に読み取るためです。他の方法は考えられません。ビデオの長さによっては、初期化時間はそれほど悪くない場合があります。

CvTrackbarsはあなたが言うように、主にパラメータを変更するために使用されます。変数の値(ポインター形式のパラメーターとして指定)を変更し、コールバック関数をスローします。残念ながら、私が知る限り、HighGUIのボタンスタイルの要素はこれらだけです。

1
n00dle

c ++およびopencv3.4の場合、frame_indexはシークしたい位置です。

Mat frame;
VideoCapture capture("test.avi");
capture.set(CAP_PROP_POS_FRAMES, frame_index);
capture>>frame;
1
XinYang

highgui ライブラリには、シークバー(cvCreateTrackbarとその仲間)の関数があります。

0
Matt Stephenson