我正在使用opencv从使用mpeg压缩的Vivotek相机的视频输出中读取帧.我正在尝试使用该函数从特定位置启动视频.如下所示,其中start是我想跳过的帧数.
inputVideo.set(CV_CAP_PROP_POS_FRAMES, start);
Run Code Online (Sandbox Code Playgroud)
但是我遇到了这个问题,因为正在捕获不正确的帧,这在帧开始之前发生.
我使用的是opencv 2.4.2版
有人可以帮忙解决这个问题吗?
Blo*_*lou 14
有点太晚了,但搜索相同的主题(不是特定于Vivotek相机,而是更多关于opencV的mpeg问题):
看到类似的问题:
CV_CAP_PROP_POS_FRAMES设置下一帧编号的问题
desired position key frame (this is where the cursor will stop)
| | | |
| > | |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Run Code Online (Sandbox Code Playgroud)
使用带轨迹板的openCV 2.4.8/VS2013的示例代码:
用MPG格式测试[MPEG1/MPEG2]:设置帧位置工作正常
double currentPos = capture.get(CV_CAP_PROP_POS_FRAMES);
std::cout << "CV_CAP_PROP_POS_FRAMES = " << currentPos << std::endl;
// position_slider 0 - 100
double noFrame = position_slider*nbFrames / 100;
// solution 1
bool success = capture.set(CV_CAP_PROP_POS_FRAMES, noFrame);
// solution 2
double frameRate = capture.get(CV_CAP_PROP_FPS);
double frameTime = 1000.0 * noFrame / frameRate;
bool success = capture.set(CV_CAP_PROP_POS_MSEC, frameTime);
if (!success) {
std::cout << "Cannot set frame position from video file at " << noFrame << std::endl;
return;
}
currentPos = capture.get(CV_CAP_PROP_POS_FRAMES);
if (currentPos != noFrame) {
std::cout << "Requesting frame " << noFrame << " but current position == " << currentPos << std::endl;
}
success = capture.read(frame_aux);
if (!success) {
std::cout << "Cannot get frame from video file " << std::endl;
return;
}
imshow("test", frame_aux);
Run Code Online (Sandbox Code Playgroud)正如 BlouBlou 所说,当你用 FFMPEG 读取一些高压缩视频格式时,它使用了“关键帧”技术来解码视频。所以设置CV_CAP_PROP_POS_FRAMES
属性不会像你想要的那样工作。
我测试了 5 个 mpeg 视频以从中读取所有帧。使用获取总帧数long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
然后我将每个视频读了两次,第一次没有设置CV_CAP_PROP_POS_FRAMES
为 0,第二次设置它。
当您设置CV_CAP_PROP_POS_FRAMES
为 0 时,它确实掉了一些帧,每个视频大约 10 帧。我猜是因为关键帧不在视频的第一帧,所以FFMPEG会跳过一些帧到第一个关键帧。但有些视频格式如.avi 不会出现这样的问题。我希望我的真实经历可以为其他人节省很多时间(我花了很长时间才找到这个页面,但已经足够了)。
无论如何,强烈建议CV_CAP_PROP_POS_FRAMES
您在面对 mpeg 格式的视频时不要使用获取特定帧。设置它是一个明智的选择CV_CAP_PROP_POS_MSEC
:)