在cvSetCaptureProperty中使用CV_CAP_PROP_POS_FRAMES获取单个帧

Ran*_*dom 10 c opencv video-processing

我试图通过设置CV_CAP_PROP_POS_FRAMES属性跳转到特定的框架,然后像这样读取框架:

cvSetCaptureProperty( input_video, CV_CAP_PROP_POS_FRAMES, current_frame );
frame = cvQueryFrame( input_video );
Run Code Online (Sandbox Code Playgroud)

我面临的问题是,OpenCV 2.1为12个连续值返回相同的帧,current_frame而我想读取每个单独的帧,而不仅仅是关键帧.谁能告诉我有什么问题?


我做了一些研究,发现问题是由解压缩算法引起的.

类似MPEG的算法(包括HD等)不会分别压缩每个帧,而是不时地保存关键帧,然后只保存最后一帧和后续帧之间的差异.

您报告的问题是由于,当您选择一个帧时,解码器(可能是ffmpeg)会自动前进到下一个关键帧.

那么,有没有办法解决这个问题呢?我不只想要关键帧,而是每个帧.

Tre*_*ude 5

我不知道这对于您的目的是否足够精确,但是我通过获取帧速率,将帧数转换为时间,然后前进到 MPEG 视频中的特定点,取得了成功时间。像这样:

cv::VideoCapture sourceVideo("/some/file/name.mpg");
double frameRate = sourceVideo.get(CV_CAP_PROP_FPS);
double frameTime = 1000.0 * frameNumber / frameRate;
sourceVideo.set(CV_CAP_PROP_POS_MSEC, frameTime);
Run Code Online (Sandbox Code Playgroud)


rum*_*pel 3

CV_CAP_PROP_POS_FRAMES 跳转到关键帧。我遇到了同样的问题,并使用这个(python-)代码解决了这个问题。它可能不完全有效,但完成了工作:

def seekTo(cap, position):
  positiontoset = position
  pos = -1
  cap.set(cv.CV_CAP_PROP_POS_FRAMES, position)
  while pos < position:
    ret, image = cap.read()
    pos = cap.get(cv.CV_CAP_PROP_POS_FRAMES)
    if pos == position:
      return image
    elif pos > position:
      positiontoset -= 1
      cap.set(cv.CV_CAP_PROP_POS_FRAMES, positiontoset)
      pos = -1
Run Code Online (Sandbox Code Playgroud)