OpenCV / CNN 神经网络 / RDK X5 BPU 图像输入格式区别
结合整套工程(MIPI→NV12→推理→预览),先给出核心结论: 三者原生偏好格式互不相同,工程里大量开销消耗在格式转换;最优方案是尽量在硬件层面完成色彩空间变换,避免 CPU 拷贝。
一、各自原生支持格式
1. OpenCV(CPU运算库)
✅原生默认:BGR24(uint8)
- imread () 读取图片 → BGR 顺序
- imshow ()、cv::Mat、传统图像处理(滤波、角点)全部基于 BGR
注意:不是 RGB!R 通道和 B 通道颠倒。
支持格式:
- 压缩文件:JPG/PNG/TIFF(文件解码后生成BGR cv::Mat,除去文件头)
- 裸流:需要自行代码把 NV12/YUYV → 转换成 cv::Mat (BGR)
- ❌ OpenCV无法直接处理 NV12 裸帧,必须软件转码;大量 NV12 <-> BGR 转换会占用 CPU。
适用场景:图像调试、画检测框、保存截图、传统视觉算法。
2. CNN 神经网络(PyTorch/TensorFlow,训练环境标准)
✅训练 & 导出 ONNX 标准输入:RGB(uint8/float32)通用规范:
- 通道顺序:RGB(和 OpenCV 的 BGR 相反),三个颜色通道。
- 维度排布:
- PyTorch:
NCHW[batch,channel, height, width]=》 height, width图像像素点。 - TensorFlow:
NHWC[batch, height, width,channel]=》 height, width图像像素点。
- PyTorch:
- 预处理:归一化(
/255.0、减均值除方差)
重点:
- 网络没有原生 YUV/NV12 支持!
- 训练时输入都是 RGB 图像;所有CNN网络的RGB的顺序相同,不同的是像素与通道的数据的排布关系!!!
- 在 PC 上训练 FCOS/YOLOv5,数据集图片加载后都是RGB。
关键分界线:PC 训练环境:只能 RGB;
部署到嵌入式开发板,可以做优化(硬件 YUV 预处理)。
3. RDK X5 BPU(地平线硬件推理单元)
✅硬件最优输入:NV12(YUV420SP)地平线 BPU 底层原生支持 NV12 输入加速,有两条路径:
路径 A【推荐,零拷贝】
NV12 帧直接送入 BPU,BPU 内置硬件单元自动完成 NV12 → RGB 色彩转换、缩放、归一化不需要 CPU 参与图像格式转换,性能最优、延迟最低。
这就是为什么mipi_cam 输出 NV12 非常适配 X5 平台。
路径 B【兼容方案】
外部先转成RGB,再喂给 BPU;
缺点:必须经过 CPU/VPS 做 NV12→RGB 拷贝,额外占用带宽,不推荐高帧率场景。
补充: BPU 只接受张量数据,不识别 JPG/RAW 文件;JPG 必须先解码,RAW 必须经过 ISP 生成 NV12。
三者格式对照表
表格
| 模块 | 原生偏好格式 | 通道顺序 | 能否直接接收 NV12 | 典型数据载体 |
|---|---|---|---|---|
| OpenCV | BGR24 | B-G-R | ❌ 不能,需要代码转换 | cv::Mat |
| CNN 网络 (ONNX 模型) | RGB24 | R-G-B | ❌ 网络算子不支持 YUV | tensor(NCHW/NHWC) |
| RDK X5 BPU | NV12(YUV420SP) | Y+UV 交错 | ✅ 原生硬件加速支持 | HBIR 模型推理输入张量 |
⚠️ 两个极易踩坑的顺序问题:
- OpenCV = BGR
- CNN 训练标准 = RGB 通道顺序颠倒 → 推理画面颜色错乱,检测精度暴跌!
二、两套工程落地链路对比(重点,适配FCOS/YOLO)
方案 1:【最优链路|推荐量产】充分利用 BPU 硬件能力
plaintext
MIPI相机 → ISP输出 NV12(/image_combine_raw) → NV12直接送入BPU → BPU硬件内部自动执行:NV12→RGB + 缩放 + 归一化 → 送入FCOS/YOLO网络推理 → CPU获取检测框 → 如需画框:截取少量图像,NV12→BGR交给OpenCV绘制优势:整条主推理链路无 CPU 图像格式拷贝,负载最低、延迟最小。 前提:导出 ONNX + 模型转换(ModelConverter)时,开启NV12 输入预处理配置。
方案 2:【调试链路|不建议长期量产】CPU 做格式转换
plaintext
NV12 → CPU调用代码转换成BGR cv::Mat(OpenCV) → OpenCV BGR → 手动调换通道转为RGB → 送入推理接口缺陷: 高分辨率 + 30fps 场景下,NV12 转 BGR 占用大量 CPU;产生内存拷贝,增加延迟。 仅适合开发调试、算法验证。
三、常见问题解析
问题 1:为什么 PC 训练 CNN 用 RGB,开发板硬件主推NV12?
PC 只有 CPU/GPU,没有 ISP;图片文件天然是 RGB/JPG。 嵌入式端相机 ISP 原生输出 NV12,如果强制转为 RGB 会额外消耗带宽;地平线把色彩转换下沉到BPU 硬件,节省 CPU。
问题 2:能不能直接把 OpenCV 的 BGR 图像喂给 BPU 推理?
可以,但要注意两点:
- BGR 需要通道调换为 RGB;
- 相比 NV12 直推方案,多一轮内存拷贝,性能变差。
问题 3:FCOS/YOLO ONNX 模型本身支持 NV12 输入吗?
❌不支持!ONNX 网络本身只认RGB 张量。NV12 支持是地平线工具链的附加硬件预处理功能: 在模型转换阶段配置参数,由 BPU 硬件在张量进入网络之前,自动完成 YUV→RGB 转换,网络本身逻辑不变。
四、工程开发标准规范
- 数据流主线:全程保留 NV12,尽量不要提前转 RGB/BGR
- 推理:使用BPU 内置 NV12 预处理,避免 CPU 图像转换
- 画框、保存截图:仅在需要的时候,局部转换 NV12→OpenCV BGR
- WebSocket预览分支:NV12 → hobot 硬件编码器生成 JPG,和推理链路互不干扰
五、最简通道流转记忆链
Sensor→ ISP:NV12(硬件原生)BPU 推理入口:优先 NV12(硬件自动转 RGB 供给 CNN)
OpenCV 交互:需要时转为BGR
CNN 网络内部:只识别RGB 张量