一、问题背景

在基于 RK3568 + HM-TM32 红外摄像头的火情监测项目中,设备录制生成了大量.avi.mp4格式视频。后续需要对视频进行批量逐帧 / 间隔抽帧,用于数据集制作、画面分析与模型迭代,但使用传统 OpenCV 读取视频时,出现全部视频打开失败、仅生成空文件夹、无法导出截图的问题。

经过排查,该类红外视频采用特殊编码格式,OpenCV 内置解码器以及CAP_DSHOW模式均无法正常解码,直接导致视频读取流程中断。针对该兼容性难题,本文提供两套基于 FFmpeg 的解决方案,一套调用系统 FFmpeg 命令行、一套基于 Python imageio库封装,均可完美兼容红外相机产出的非常规编码视频,实现批量间隔抽帧,适用于 Windows 平台批量视频处理场景。

二、问题复现与原因分析

1. 故障现象

使用 OpenCV 编写视频抽帧代码后,程序可以正常遍历目录、为每个视频创建同名存储文件夹,但控制台持续输出Open failed,所有.avi.mp4文件均读取失败,文件夹内无任何截图生成。

2. 根因

HM-TM32 红外摄像头输出的视频为专用编码,并非通用标准视频编码。OpenCV 原生解码器、Windows 下CAP_DSHOW多媒体接口对这类非标编码兼容性极差,无法解析视频流,最终表现为视频打开失败。想要正常解码,必须依托FFmpeg全能解码引擎。

imageio 封装 FFmpeg,纯 Python 实现

打开 CMD 执行命令安装依赖:

pip install imageio imageio-ffmpeg

调用 FFmpeg 命令行批量间隔抽帧

import imageio
import os

VIDEO_ROOT = r"D:\图像处理\venv\fire_videos"
SUPPORT_FORMAT = (".avi", ".mp4")
SAMPLE_INTERVAL = 5

def extract_frames(video_path):
    video_name = os.path.splitext(os.path.basename(video_path))[0]
    save_dir = os.path.join(VIDEO_ROOT, video_name)
    os.makedirs(save_dir, exist_ok=True)
    try:
        reader = imageio.get_reader(video_path, "ffmpeg")
        frame_idx = 0
        save_count = 0
        for frame in reader:
            if frame_idx % SAMPLE_INTERVAL == 0:
                frame_path = os.path.join(save_dir, f"frame_{frame_idx:04d}.jpg")
                imageio.imwrite(frame_path, frame)
                save_count += 1
            frame_idx += 1
        reader.close()
        print(f"{video_name} | Total:{frame_idx} | Saved:{save_count}")
    except Exception as e:
        print(f"Error: {video_path} -> {e}")

if __name__ == "__main__":
    if not os.path.isdir(VIDEO_ROOT):
        print("Directory not exist")
        exit()
    for file in os.listdir(VIDEO_ROOT):
        full_path = os.path.join(VIDEO_ROOT, file)
        if os.path.isfile(full_path):
            ext = os.path.splitext(file)[1].lower()
            if ext in SUPPORT_FORMAT:
                extract_frames(full_path)
    print("Process finished")

运行注意事项

  1. 关闭文件占用 运行代码前,关闭所有视频播放器、资源管理器预览窗口、剪辑软件,视频被进程占用会导致解码失败。
  2. 权限问题 若出现权限报错,右键 Python 终端、IDE,选择以管理员身份运行
  3. 抽帧间隔调试 如需逐帧提取画面,将SAMPLE_INTERVAL修改为1即可。
  4. FFmpeg 部署检查 使用方案一时,务必保证ffmpeg.exe可正常调用,可在 CMD 输入ffmpeg -version验证是否配置成功。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐