无法使用 C++ 和 OpenCV 从视频中提取帧

Posted

技术标签:

【中文标题】无法使用 C++ 和 OpenCV 从视频中提取帧【英文标题】:Can't extract frames from video using C++ with OpenCV 【发布时间】:2018-01-08 09:14:01 【问题描述】:

我想从一个简短的 .mp4 视频中提取所有帧并将它们作为图像保存到文件夹中。但是当我调用函数 cv::VideoCapture::read() 时,它无法提取帧。我的代码有什么问题?

#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/videoio.hpp>

int main(int argc, const char * argv[]) 
     cv::VideoCapture cap("test.mp4");

     if (!cap.isOpened()) 
         std::cout << "Cannot open the video file.\n";
         return -1;
     

     for (int frame_count = 0; frame_count < cap.get(cv::CAP_PROP_FRAME_COUNT); frame_count++) 
          cap.set(cv::CAP_PROP_POS_FRAMES, frame_count);
          cv::Mat frame;

          if (!cap.read(frame)) 
              std::cout << "Failed to extract a frame.\n";
              return -1;
          

          std::string image_path = "frames/" + std::to_string(frame_count) + ".jpg"; 
          cv::imwrite(image_path, frame);
    

    return 0;

我的输出总是“提取帧失败”。

【问题讨论】:

你试过没有 cap.set 吗?假设在 for 循环之外。 cap.get(cv::CAP_PROP_FRAME_COUNT) 返回什么? @api55 刚试了下,也提取帧失败。无需调用 cap.set() 并在循环之外。 cap.get(cv::CAP_PROP_FRAME_COUNT) 返回 70 尝试分别使用抓取和检索(而不是读取)。您是否尝试过其他视频?也许用另一个编解码器? 您的平台和 OpenCV 版本是什么?你是从源代码编译它还是下载二进制文件? @api55 刚刚尝试了另一个视频并且成功了!奇怪的是,它是用同一部手机拍摄的。但我尝试使用的第一个视频是从 iPhone 上传到运行 php 服务器脚本的计算机。我假设我以某种方式错误地保存了它(在那个 PHP 脚本中)。因为该视频的编解码器是:hvc1、AAC 和 mebx,而它使用的编解码器是 AAC 和 H.264。我的错,谢谢你的帮助! 【参考方案1】:

在你provided above的教程上,有一条指令:

取消选中 WITH_FFMPEG

ffmpeg 库包含 mp4 编解码器,您需要检查 WITH_FFMPEGUSE_FFMPEG 才能读取 .mp4 和许多其他格式。

【讨论】:

哇!十分感谢!我对 CMake 没有经验。如果我再次按照说明检查这些标志,它会重新编译库,还是我需要以某种方式删除与 OpenCV 相关的所有内容并再次按照教程进行操作?如果我只下载最新版本的 OpenCV 并再次按照这些说明操作可以吗? @VolodymyrDenysov 您需要在另一个目录中重新编译带有 WITH_FFMPEG 标志的 Opencv,并且必须显示新编译路径的路径

以上是关于无法使用 C++ 和 OpenCV 从视频中提取帧的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenCV 仅在视频文件开头几秒钟提取帧

Python opencv 无法从视频中裁剪帧

调试一种在 C++ 中使用 OpenCV 从视频中寻找运动平均帧以进行运动检测的方法

从视频中提取帧的最快方法

使用 Opencv 加速从摄像头读取视频帧

改进了从视频中提取缩略图