26

我一直在尝试使用 C++ 中的 OpenCV 查找/实现查找和倒带功能(用于视频(.avi)),但除了遍历整个文件并保存每个图像之外,我找不到这样做的方法。还有其他方法吗?

任何帮助将非常感激; 提前谢谢!

4

4 回答 4

47

使用 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 字符代码(仅适用于相机)。

前两个是你感兴趣的。

编辑:更多信息:)

您可以通过使用各种帧索引重复调用上述函数来循环帧。

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)
于 2010-06-05T16:51:10.397 回答
1

我认为您必须将整个文件读入 IplImages 数组,然后完成它。原因是,cvQueryFrame 是一个单向进程,它按顺序一次读取一帧。我想不出别的办法。根据视频的长度,初始化时间可能不会太糟糕。

正如你所说,cvTrackbars 主要用于更改参数。它们改变变量的值(以指针形式作为参数给出)并抛出一个回调函数。不幸的是,据我所知,它们是 HighGUI 中唯一的按钮样式元素

于 2010-06-04T14:02:44.337 回答
1

对于 C++ 和 opencv3.4,frame_index 是您要寻找的位置。

Mat frame;
VideoCapture capture("test.avi");
capture.set(CAP_PROP_POS_FRAMES, frame_index);
capture>>frame;
于 2018-07-30T04:56:30.977 回答
0

highgui库中,您会找到用于搜索栏的函数(cvCreateTrackbar 和朋友)。

于 2010-06-04T13:48:09.230 回答