You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV视频帧处理调用cvtColor报!_src.empty()错误排查

视频帧转张量C++代码崩溃排查

问题现象

  • 实现目标:在视频播放流程中完成视频帧到张量的转换,后续用于逐帧推理提取关键点
  • 依赖组件:OpenCV库、自定义VideoProcessing模块
  • 崩溃报错:程序启动后直接触发cv::Exception异常终止,错误输出:
terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.1.0) /home/onur/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

Aborted (core dumped)

错误原因

报错的直接触发逻辑是cv::cvtColor函数的前置校验失败:该函数要求传入的源图像Mat不能为空,而代码传入的是未初始化的空Mat。
根本问题是循环内的代码执行顺序完全写反:

  1. 进入while循环后首先声明了空的cv::Mat frame对象,没有任何有效赋值
  2. 立刻对这个空对象执行convertTo类型转换、cvtColor颜色空间转换、像素归一化、resize缩放操作
  3. 所有预处理操作都跑完了,才调用cap.read(frame)从视频流中读取实际的帧数据
    第一次进入循环执行cvtColor时,frame里没有任何图像数据,直接触发断言崩溃。
    除此之外该逻辑还有功能性错误:就算跳过空帧校验,预处理操作执行时还没读到当前帧,处理的是上一轮循环残留的旧数据,完全不符合张量转换的需求。

修复方法

把帧读取操作移动到循环内所有帧处理逻辑的最前端,读取完成后先校验帧是否有效,校验通过再执行后续预处理步骤,修正后的循环核心代码如下:

while(true){
    cv::Mat frame;
    // 优先读取当前帧
    bool success = cap.read(frame);
    // 帧读取失败(到视频末尾/读取出错)直接退出循环
    if (!success){
        std::cout << "Found the end of the video" << std::endl;
        break;
    }

    // 确认读到有效帧后再执行预处理
    frame.convertTo(frame, CV_32FC3);
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB); // BGR转RGB,同时转换为浮点类型

    // 像素值归一化到[-1, 1]区间
    auto* pixel = frame.ptr<Pixel>(0,0);
    const Pixel* endPixel = pixel + frame.cols * frame.rows;
    for (; pixel != endPixel; pixel++){normalize(*pixel);}

    // 缩放到模型要求的输入尺寸
    cv::resize(frame, frame, cv::Size(WIDTH, HEIGHT));

    // 展示处理后的帧
    cv::imshow("input video", frame);
    if (cv::waitKey(10) == 27){
        std::cout << "Esc key is pressed by user. Stopping the video" << std::endl;
        break;
    }
}

内容的提问来源于stack exchange,提问作者mchd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:30:39