使用OpenCV的C++ API抽取mp4为png时,发现CV_CAP_PROP_POS_MSEC属性居然在OpenCV 3.3.0版本下失效。
一、需求
- 把mp4等时间间隔抽取为png
- 环境:Mac OS
- 语言:C++
- 抽取间隔:50ms
二、问题描述
在OpenCV 3.2.0下可以按如下方式实现(简化代码):
VideoCapture *cap = new VideoCapture("/path/to/video");
Mat lastFrame;
int count = 100;
while (--count >= 0) {
// 等时间间隔抽取图片
cap->set(CV_CAP_PROP_POS_MSEC, count * 50);
Mat frame;
// 获取帧
cap->read(frame);
if (frame.empty()) {
break;
}
// 获得此帧据mp4开始的时间间隔,单位ms
long timeFromBegin = static_cast<long>(cap->get(CV_CAP_PROP_POS_MSEC));
try {
string outputDir = "/path/to/output";
stringstream ss;
string fileName;
vector<int> compression_params;
compression_params.push_back(16);
compression_params.push_back(9);
ss << outputDir << "/" << timeFromBegin << ".png" << endl;
ss >> fileName;
// 写入文件
imwrite(fileName, frame, compression_params);
} catch (cv::Exception &ex) {
cout << "Caught error " << ex.what() << endl;
}
}
然而,某天手一抖
brew update
brew upgrade
发现OpenCV升级到了3.3.0。。。
偶然间发现,之前写的等间隔抽取mp4的代码的精度出现了严重的问题,通过brew switch把OpenCV降级到3.2.0后问题消失。
怀疑在OpenCV 3.3.0上,cap->set(CV_CAP_PROP_POS_MSEC, count * 50)失效,不知道为什么,可能是只读取了关键帧,而不是下一个50ms吧,。
时间有限,先这么记录。