OpenCV没有报告准确的帧率/计数 [英] OpenCV doesn't report accurate frame rate/count

查看:117
本文介绍了OpenCV没有报告准确的帧率/计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个33秒的视频,我正在尝试使用OpenCV处理.我的目标是确定每帧对应的时间实例(相对于视频的开始).我这样做是为了能够比较同一场景的视频中以不同帧频记录的帧.

I have a 33 second video that I'm trying to process with OpenCV. My goal is to determine what instance in time (relative to the start of the video) each frame corresponds to. I'm doing this in order to be able to compare frames from videos of the same scene that have been recorded at different frame rates.

工作原理:

  • FPS正确报告为59.75.这与ffprobe的报告一致,因此我很高兴相信这是正确的.
  • The FPS is correctly reported as 59.75. This is consistent with what ffprobe reports, so I'm happy to believe that's correct.

我遇到的问题是:

  • CAP_PROP_POS_MSEC返回的值不正确.到视频结束时,它最多达到557924毫秒(9分钟以上).对于33秒钟的视频,这是不对的.
  • CAP_PROP_FRAME_COUNT也不正确.据报道为33371,以59.75 fps的速度拍摄超过9分钟的镜头.符合上述错误,但仍然不正确.
  • CAP_PROP_POS_FRAME同样是不正确的.
  • CAP_PROP_POS_MSEC returns incorrect values. By the end of the video, it's up to 557924ms (over 9 min). For a 33s video, this can't be right.
  • CAP_PROP_FRAME_COUNT is also incorrect. It's reported as 33371, which at 59.75 fps would give over 9 minutes worth of footage. Consistent with the above error, but still incorrect.
  • CAP_PROP_POS_FRAME is similarly incorrect.

可以在此处找到该视频(约10MB).

The video can be found here (approx. 10MB).

关于可能出什么问题的任何想法吗?

Any ideas on what could be wrong?

ffprobe输出:

FFprobe version SVN-r20090707, Copyright (c) 2007-2009 Stefano Sabatini
  libavutil     49.15. 0 / 49.15. 0
  libavcodec    52.20. 0 / 52.20. 1
  libavformat   52.31. 0 / 52.31. 0
  built on Jan 20 2010 00:13:01, gcc: 4.4.3 20100116 (prerelease)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/misha/Dropbox/Public/sequence.mp4':
  Duration: 00:00:33.37, start: 0.000000, bitrate: 2760 kb/s
    Stream #0.0(und): Video: h264, yuv420p, 1920x1080, 59.75 tbr, 1k tbn, 2k tbc
    Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16

完整代码:

#include <iostream>
#include <assert.h>

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

#include <cmath>
#include <iostream>
#include <string.h>
#include <stdio.h>

extern "C"
{
#include "options.h"
}

using namespace std;

#define DEBUG 0

static void
print_usage(char *argv0)
{
    cerr << "usage: " << argv0 << " video.avi [options]" << endl;
}

int main(int argc, char** argv)
{
    if (argc < 2)
    {
        print_usage(argv[0]);
        return -1;
    }

    int           step      = 30;
    struct Option options[] =
    {
        { "step",        1, &step },
        { NULL,          0, NULL }
    };

    int ret = parse_options(2, argc, argv, options);
    if (ret == 0)
    {
        print_usage(argv[0]);
        return -1;
    }

    CvCapture *capture = cvCaptureFromFile(argv[1]);
    int counter = 0;
    while (cvGrabFrame(capture))
    {
        ++counter;

        IplImage *frame = cvRetrieveFrame(capture);
        double millis   = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC);
        double current  = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
        double total    = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
        printf("%d %d/%d %f\n", counter, (int)current, (int)total, millis);
        int min = (int)(millis/1000/60);
        millis -= min*60000;
        int sec = (int)(millis/1000);
        millis -= sec*1000;

        printf("%d %02d:%02d:%f\n", counter, min, sec, millis);
    }
    cvReleaseCapture(&capture);

    return 0;
}

推荐答案

始终告知您使用的软件版本:您使用的是哪个OpenCV版本?您的可能是旧版本,因此请尽可能更新到最新版本.

Always inform the software version you are using: which OpenCV version are you using for that? Yours might be an old version, so update to the most recent if possible.

如果您的视频文件是其他一些较大视频的一部分,则此信息实际上可能是正确的,因为:

If your video file is part of some other larger video, this information might actually be correct, since:

CV_CAP_PROP_POS_MSEC - film current position in milliseconds or video capture timestamp

OpenCV可能只是从文件头读取所有这些东西,这显然是错误的.如果有人使用斧头(或其他中世纪工具)从原始视频中剥离了该片段,则可能会发生这种情况.

OpenCV might be simply reading all these stuff from the file header, which is obviously wrong. This could happen if someone used an ax (or other medieval tool) to strip this piece from the original video.

您应该尝试制作的视频,并且知道它们没有被篡改.

You should try with videos that you made and you know they haven't been tampered with.

最坏的情况是,您将必须自己实现这些功能.没关系.

Worst case scenario, you will have to implement these features yourself. No biggie.

@misha起初我没有注意到您正在使用:

@misha I didn't notice at first that you are using:

CvCapture *capture = cvCaptureFromFile(argv[1]);

如果可以的话,将其替换为 cvCaptureFromAVI(),并始终检查OpenCV调用的返回值:

Replace it for cvCaptureFromAVI() if you can, and ALWAYS check the return value of OpenCV calls:

CvCapture *capture = cvCaptureFromAVI(argv[1]);
if(!capture) 
{
    printf("!!! cvCaptureFromAVI failed (file not found?)\n");
    return -1; 
}

几天前,我分享了一个代码,该代码

A few days ago I shared a code that uses OpenCV to read a video file and then save the frames as JPG images on the disk. It also reports the current FPS using the traditional cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); so it could be interesting for you to take a look at that. Go check it out.

您还应该检查此线程关于使用OpenCV的帧计数;

You should also check this thread about frame count using OpenCV;

顺便说一下,我只是在Ubuntu系统上更新了一些库,并重新编译了 OpenCV-2.1.0.tar.bz2 (使用 cmake ).我更改了源代码(使用 cvCaptureFromAVI())以在每个帧上使用调试方法打印内容.看来可行:

By the way, I just updated some libraries on my Ubuntu system and recompiled OpenCV-2.1.0.tar.bz2 (using cmake). I changed my source code (that uses cvCaptureFromAVI()) to print stuff using your debug method on each frame. It seems it works:

* Filename: sequence.mp4
* FPS: 59
...
...
...
17 00:00:567.000000
18 601/33371 601.000000
18 00:00:601.000000
19 634/33371 634.000000
19 00:00:634.000000
20 668/33371 668.000000
20 00:00:668.000000
21 701/33371 701.000000
21 00:00:701.000000
22 734/33371 734.000000
22 00:00:734.000000
23 768/33371 768.000000
23 00:00:768.000000
24 801/33371 801.000000
24 00:00:801.000000
25 835/33371 835.000000
25 00:00:835.000000
26 868/33371 868.000000
26 00:00:868.000000
27 901/33371 901.000000
27 00:00:901.000000
28 935/33371 935.000000
... 

这篇关于OpenCV没有报告准确的帧率/计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆