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

如何从OpenCV DNN生成的4维cv::Mat blob中提取单个颜色通道

你遇到的问题根源是对OpenCV DNN模块输出的blob内存排布规则理解有误,以及构造提取通道的Mat时参数设置错误。

OpenCV dnn::blobFromImage的存储逻辑

cv::dnn::blobFromImage 默认输出NCHW排布的4维Mat,4个维度依次为:

  • 第0维:batch size,你的场景下固定为1
  • 第1维:通道数,你的场景下为3,因为你设置了swapRB=false,所以通道顺序为B、G、R
  • 第2维:输入图像高度,你的场景下为224
  • 第3维:输入图像宽度,你的场景下为244

内存是连续紧凑存储的,存储顺序为:先完整存储B通道的所有224*244个uint8像素,再完整存储G通道的所有像素,最后完整存储R通道的所有像素,和普通OpenCV cv::Mat默认的BGR交错存储(每个像素点按B、G、R三个值依次存储)逻辑完全不同。

现有代码的错误点

  1. 构造blueImg时指定了CV_8UC3类型,相当于把连续存储的单通道B像素数据,按照每3个值对应一个像素的3通道格式解析,必然会出现内容错乱,也就是你现在看到的异常输出结果
  2. 代码存在语法遗漏:构造函数最后一个参数的右括号缺失,编译阶段会报错

正确的实现方案

单通道提取代码

// 先确认blob维度符合预期,可选调试代码
CV_Assert(blob.dims == 4 && blob.size[0] == 1 && blob.size[1] ==3);
int h = blob.size[2];
int w = blob.size[3];

// 提取B通道(第1个通道,索引0)
cv::Mat blueImg(h, w, CV_8UC1, blob.ptr<uint8_t>(0, 0));
// 提取G通道(第2个通道,索引1)
cv::Mat greenImg(h, w, CV_8UC1, blob.ptr<uint8_t>(0, 1));
// 提取R通道(第3个通道,索引2)
cv::Mat redImg(h, w, CV_8UC1, blob.ptr<uint8_t>(0, 2));

还原为普通BGR三通道Mat(可选,用于和原图对比验证)

cv::Mat recoveredBgr;
std::vector<cv::Mat> channels = {blueImg, greenImg, redImg};
cv::merge(channels, recoveredBgr);
// 此时可直接imshow查看recoveredBgr,和原始输入m_inputImg完全一致

额外注意事项

  • 如果调用blobFromImage时设置了swapRB=true,则通道顺序变为R、G、B,提取后merge时需要调整通道顺序对应索引
  • 如果传入了非1的缩放系数、或者设置了减均值参数,提取的像素值会和原始图像有差异,属于正常预处理结果
  • 如果设置了crop=true,blob存储的是裁剪后的图像内容,和原图大小会有差异

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:06:04