【坑】OpenCV等毫秒级间隔抽取mp4为png

使用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吧,。
时间有限,先这么记录。

你可能感兴趣的:(Other)