【发布时间】:2023-03-04 13:58:02
【问题描述】:
我正在尝试使用 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;
}
【问题讨论】:
-
你使用的是哪一个:Windows/Linux/Mac?
-
Linux (Ubuntu 10.04 LTS)
-
这解释了很多。 OpenCV 仍在努力改进对 Linux 下视频文件的支持,抱歉。
标签: c++ video opencv video-processing