解决C++ openCV无法读取视频但是可以读取图像

C++代码中使用 cv::VideoCapture 读取视频文件时,视频文件路径正确,依然无法读取视频。

我的发现并解决过程(简易版):

1. 确保图片可以正常读取

路径正确!

有读取权限!

读取图像可以成功!

2. 检查 OpenCV 编译配置

确保 OpenCV 支持 MP4 格式的视频解码。你可以检查 OpenCV 编译时是否启用了 FFmpeg:
bash cv::getBuildInformation()

查看是否包含 FFmpeg,如果没有,你可能需要重新编译 OpenCV 支持 FFmpeg。

果然把上面的结果打印出来没看到的FFmpeg相关的内容,大概锁定原因。可能是无法读取 MP4 文件的关键原因。在 OpenCV 中,MP4 文件的读取通常依赖 FFmpeg 库来进行解码。

3. 解决方法1:重新编译 OpenCV,启用 FFmpeg

需要重新编译 OpenCV,并确保包含 FFmpeg 支持。编译步骤大致如下:

  • 下载 FFmpeg 源码并进行编译,生成静态或动态库。

  • 重新编译 OpenCV 时,确保启用了 FFmpeg 支持:

    bash 复制代码
    cmake -D CMAKE_BUILD_TYPE=Release \
          -D CMAKE_TOOLCHAIN_FILE=<your_android_toolchain> \
          -D WITH_FFMPEG=ON \
          -D OPENCV_ENABLE_NONFREE=ON \
          -D BUILD_opencv_videoio=ON \
          -D BUILD_opencv_highgui=ON \
          <other_flags> \
          ..

    确保 WITH_FFMPEG=ON,并且 BUILD_opencv_videoio=ON

或在 CMakeLists.txt 中,指定 FFmpeg 的路径:

bash 复制代码
cmake -DWITH_FFMPEG=ON -DFFMPEG_DIR=/path/to/ffmpeg ..

4. 解决方法2:检查其他视频 I/O 支持(不推荐)

如果不想重新编译 OpenCV,的确有点麻烦。如果在Android平台运行,则可以使用 Android 的原生 API(如 MediaPlayerMediaCodec)来加载视频,并将每一帧转换为 OpenCV 可处理的格式(如 cv::Mat)。

5. 解决方法3:使用图片序列替代视频(不推荐)

如果不需要处理原始视频,可以使用之前提到的图片序列方案,将视频转换为帧图片,再通过 OpenCV 逐帧读取。

6. 解决方法4:使用特定格式的视频文件(推荐!!!)

OpenCV 可以处理不依赖 FFmpeg 的视频格式,例如:

  • MJPEG (Motion JPEG):这是一个简单的编码格式,基本上就是一组 JPEG 图片组成的视频流。(推荐直接用这个,直接可以预览,文件也小,方便迁移)
  • RAW 格式 :如果你能将视频转码为 AVI 的 RAW 格式(没有压缩),那么 OpenCV 通常能够直接读取。(这个贼大,好不一定可以直接预览,略不方便)

可以通过系统指令或者python脚本直接进行视频格式的转换,这样你的avi视频就可以直接被opencv读取了而且不依赖FFmpeg。

下面我直接给出了Python转视频格式的例子:

可以借助 ffmpeg-python 库将 MP4 格式的视频转换为 MJPEG 或 RAW AVI 格式。ffmpeg-python 是 FFmpeg 的 Python 封装,提供了简单的接口来调用 FFmpeg。

首先,需要安装 ffmpeg-python 库:

bash 复制代码
pip install ffmpeg-python

然后,可以使用以下 Python 代码将 MP4 视频转换为 MJPEG 和 RAW AVI 格式:

转换为 MJPEG 格式

python 复制代码
import ffmpeg

input_file = '/path/to/input.mp4'
output_file_mjpeg = '/path/to/output_mjpeg.avi'

ffmpeg.input(input_file).output(output_file_mjpeg, vcodec='mjpeg', qscale_v=2).run()

转换为 RAW AVI 格式

python 复制代码
import ffmpeg

input_file = '/path/to/input.mp4'
output_file_raw = '/path/to/output_raw.avi'

ffmpeg.input(input_file).output(output_file_raw, vcodec='rawvideo', pix_fmt='yuv420p').run()
相关推荐
小东来30 分钟前
电脑端视频剪辑软件哪个好用,十多款剪辑软件分享
音视频
Lenyiin1 小时前
《 C++ 修炼全景指南:十 》自平衡的艺术:深入了解 AVL 树的核心原理与实现
数据结构·c++·stl
程序猿练习生2 小时前
C++速通LeetCode中等第5题-无重复字符的最长字串
开发语言·c++·leetcode
shiming88792 小时前
MATLAB图像处理
图像处理·计算机视觉·matlab
无名之逆2 小时前
云原生(Cloud Native)
开发语言·c++·算法·云原生·面试·职场和发展·大学期末
好蛊2 小时前
第 2 课 春晓——cout 语句
c++·算法
cuijiecheng20183 小时前
音视频入门基础:AAC专题(8)——FFmpeg源码中计算AAC裸流AVStream的time_base的实现
ffmpeg·音视频·aac
Mr数据杨3 小时前
我的AI工具箱Tauri版-VideoIntroductionClipCut视频介绍混剪
人工智能·音视频
神一样的老师3 小时前
基于环境音频和振动数据的人类活动识别
人工智能·音视频
启明云端wireless-tag3 小时前
设备稳定流畅视频体验,乐鑫ESP32-S3芯片方案无线音视频传输通信
物联网·音视频·交互·乐鑫·wifi模组