使用 capture.get(CV_CAP_PROP_FPS) 时 OpenCV 报告 TBR 而不是 FPS
Posted
技术标签:
【中文标题】使用 capture.get(CV_CAP_PROP_FPS) 时 OpenCV 报告 TBR 而不是 FPS【英文标题】:OpenCV Reporting TBR instead of FPS when using capture.get(CV_CAP_PROP_FPS) 【发布时间】:2012-03-13 01:58:48 【问题描述】:我尝试在 Mac OS 10.6.8 (Snow Leopard) 上使用 OpenCV 和 Qt 4.7.4 处理几个视频。如果我创建一个cv::VideoCapture
对象,然后查询与此类视频相关的帧速率,我得到的是 TBR 而不是 FPS。
例如,如果使用ffprobe Video1.mp4
,我得到的是:
>> ffprobe Video1.mp4
ffprobe version 0.7.8, Copyright (c) 2007-2011 the FFmpeg developers
built on Nov 24 2011 14:31:00 with gcc 4.2.1 (Apple Inc. build 5666) (dot 3)
configuration: --prefix=/opt/local --enable-gpl --enable-postproc --enable-swscale --
enable-avfilter --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-
libdirac --enable-libschroedinger --enable-libopenjpeg --enable-libxvid --enable-libx264
--enable-libvpx --enable-libspeex --mandir=/opt/local/share/man --enable-shared --
enable-pthreads --cc=/usr/bin/gcc-4.2 --arch=x86_64 --enable-yasm
libavutil 50. 43. 0 / 50. 43. 0
libavcodec 52.123. 0 / 52.123. 0
libavformat 52.111. 0 / 52.111. 0
libavdevice 52. 5. 0 / 52. 5. 0
libavfilter 1. 80. 0 / 1. 80. 0
libswscale 0. 14. 1 / 0. 14. 1
libpostproc 51. 2. 0 / 51. 2. 0
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Video1.mp4':
Metadata:
major_brand : isom
minor_version : 0
compatible_brands: mp41avc1qt
creation_time : 2012-01-09 23:09:43
encoder : vlc 1.1.3 stream output
encoder-eng : vlc 1.1.3 stream output
Duration: 00:10:10.22, start: 0.000000, bitrate: 800 kb/s
Stream #0.0(eng): Video: h264 (Baseline), yuvj420p, 704x480 [PAR 10:11 DAR 4:3], 798
kb/s, 27.71 fps, 1001 tbr, 1001 tbn, 2002 tbc
Metadata:
creation_time : 2012-01-09 23:09:43
正确报告 FPS = 27.71 和 TBR = 1001。不过,如果我使用以下 OpenCV 代码查询 FPS:
QString filename = QFileDialog::getOpenFileName(this,
"Open Video",
"Video Files (*.mp4, *.mpg)");
capture.release();
capture.open(filename.toAscii().data());
if (!capture.isOpened())
qDebug() <<"Error when opening the video!";
return;
qDebug() << "Frame Rate:" << capture.get(CV_CAP_PROP_FPS);
qDebug() << "Num of Frames:" << capture.get(CV_CAP_PROP_FRAME_COUNT);
qDebug() << "OpenCV Version" << CV_VERSION;
我得到的输出是:
Frame Rate: 1001
Num of Frames: 610832
OpenCV Version 2.3.1
报告 TBR 而不是 FPS。当我尝试打开不同的视频时,这种行为是一致的。
我检查了 OpenCV 的 bug tracker 并且我还发现 this 堆栈溢出问题是一个类似但不完全相同的问题,所以我不知道下一步该做什么。任何提示或想法都是最受欢迎的,因为我尝试了很多东西,但似乎无济于事。
【问题讨论】:
【参考方案1】:我想他们之所以选择报告 TBR,是因为那是 ffmpeg's best guess 关于帧速率的实际值。在许多容器上,fps 字段(更具体地说是AVStream.avg_frame_rate
)不可用,因此不能真正依赖它。
以下是来自ffmpeg
源的 tbr、tbc 和 tbn 字段的 cmets:
TBR(ffmpeg 的最佳猜测):
struct AVStream
...
/**
* Real base framerate of the stream.
* This is the lowest framerate with which all timestamps can be
* represented accurately (it is the least common multiple of all
* framerates in the stream). Note, this value is just a guess!
* For example, if the time base is 1/90000 and all frames have either
* approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
*/
AVRational r_frame_rate;
TBC(编解码器时基):
struct AVCodecContext
...
/**
* This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* time base should be 1/framerate and timestamp increments should be 1.
* decoding: set by libavformat
* encoding: set by libavformat in av_write_header
*/
AVRational time_base;
TBN(流(容器)时基):
struct AVStream
...
/**
* This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identically 1.
* - encoding: MUST be set by user.
* - decoding: Set by libavcodec.
*/
AVRational time_base;
希望这可以解释为什么报告的是 TBR 而不是 FPS。 ffmpeg
似乎很难确定视频流的时间基准,并且容器(例如,AVI、MP4、DivX、XviD 等)提供帧速率,因此 ffmpeg
会显示它,即使它可以不是通过分析来确定的。是否可以正确重新编码视频?
【讨论】:
重新编码视频虽然可行,但会很麻烦,因为视频很多而且有点长。它们是从网络摄像机生成的。但是您的回答清楚地解释了为什么我得到 TBR 而不是 FPS。谢谢!以上是关于使用 capture.get(CV_CAP_PROP_FPS) 时 OpenCV 报告 TBR 而不是 FPS的主要内容,如果未能解决你的问题,请参考以下文章