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。
根本问题是循环内的代码执行顺序完全写反:
- 进入while循环后首先声明了空的
cv::Mat frame对象,没有任何有效赋值 - 立刻对这个空对象执行
convertTo类型转换、cvtColor颜色空间转换、像素归一化、resize缩放操作 - 所有预处理操作都跑完了,才调用
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
相关产品推荐
相关产品推荐

