gpt4 book ai didi

c++ - OpenCV 不报告准确的帧速率/计数

转载 作者:IT老高 更新时间:2023-10-28 23:02:12 24 4
gpt4 key购买 nike

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

什么工作:

  • FPS 正确报告为 59.75。这与 ffprobe 报告的内容一致,因此我很高兴相信这是正确的。

我遇到的问题是:

  • CAP_PROP_POS_MSEC 返回不正确的值。到视频结束时,最长为 557924 毫秒(超过 9 分钟)。对于 33 多岁的视频,这是不对的。
  • CAP_PROP_FRAME_COUNT 也不正确。它被报告为 33371,以 59.75 fps 的速度可以提供超过 9 分钟的镜头。与上述错误一致,但仍然不正确。
  • CAP_PROP_POS_FRAME 同样不正确。

视频可以找到here (约 10MB)。

对可能出现的问题有任何想法吗?

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 版本?您的可能是旧版本,因此请尽可能更新到最新版本。

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

CV_CAP_PROP_POS_MSEC - film current position in milliseconds or video capture timestamp

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

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

在最坏的情况下,您必须自己实现这些功能。没什么大不了的。

编辑:@misha 我一开始并没有注意到你在使用:

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

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

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

几天前我分享了一个代码 uses OpenCV to read a video file and then save the frames as JPG images on the disk .它还使用传统的 cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); 报告当前 FPS,因此您可能会感兴趣看看它。去看看吧。

编辑:

您还应该检查 this thread关于使用 OpenCV 的帧数;

顺便说一句,我刚刚在我的 Ubuntu 系统上更新了一些库并重新编译了 OpenCV-2.1.0.tar.bz2(使用 cmake)。我更改了我的源代码(使用 cvCaptureFromAVI())以在每一帧上使用您的调试方法打印内容。似乎有效:

* 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
...

关于c++ - OpenCV 不报告准确的帧速率/计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4352939/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com