相机 RGA 硬件加速实战:把图像预处理从 CPU 搬到 2D 加速单元
一、相机预处理是怎么拖垮检测的
做智能摄像头、机器人视觉的人几乎都踩过同一个坑:摄像头采集的 YUV 数据哗啦啦地进来,你的检测模型嗷嗷待哺地等着 RGB 输入,中间还得做缩放、裁剪、旋转。
你一开始图省事,用 OpenCV 的 cvtColor + resize 在 CPU 上跑。结果画面一复杂、分辨率一高,CPU 占用直接飙到七八十,帧率掉得惨不忍睹,整个板子热得能煎鸡蛋。
这就是典型的「CPU 预处理瓶颈」:算法本身还没发力,数据搬运和格式转换就把系统拖垮了。问题根子在——YUV 转 RGB、缩放、裁剪这些 2D 图像操作,根本不该占用通用 CPU 的算力。
以 Rockchip RK3588 上一块四路 1080P 智能门禁为例:每路都要把 NV12 格式的 YUV 流实时转成 RGB,并缩放到模型要的 300×300。纯 CPU 方案下,四核 A76 全开、占用率接近 100%,帧率勉强 15 帧,延迟肉眼可见。
二、RGA 是什么:Rockchip 的 2D 图像加速单元
这时候,RK3588 内置的一个「神器」该登场了——RGA(Raster Graphic Acceleration,光栅图形加速单元)。
你可以把它理解成一颗专门处理 2D 图像操作的「副驾」芯片。它不归 CPU 管,自己有一套独立硬件电路,专干这几件脏活累活:
- 裁剪(crop):只取画面中间一块
- 缩放(resize):放大或缩小
- 旋转(rotate):转 90°、180°、翻转
- 格式转换(format convert):比如 NV12(YUV420)↔ RGB888
最妙的是,它干活的时候 CPU 几乎可以「喝茶看报」,把宝贵的算力留给更复杂的 AI 推理、检测这些核心任务。把预处理流水线全部迁移到 RGA 上后,上面那个四路门禁的 CPU 占用直接降到个位数,四路都能稳定跑 30 帧,整体功耗还降了约 20%——这就是硬件加速最直观的收益。
RGA 在 Rockchip 的媒体流水线里处在「VI(视频输入)」和「检测/推理」之间:
1 | 摄像头(VI, NV12 流) |
三、核心概念:通道、绑定与零拷贝
理解 RGA,先搞清三个关键点:
(1) VI → RGA → 检测 的「绑定」。 Rockchip 用一套 MPI(Media Process Interface)框架把硬件模块连成流水线。你不用直接操作 RGA 的寄存器,只要通过 RK_MPI_SYS_Bind 把 VI 通道「绑」到 RGA 通道,系统会自动把每一帧送进 RGA 处理。
(2) 多通道并行。 一个 VI 源可以同时绑到多个 RGA 通道,每个通道配置不同的裁剪区域/输出尺寸/旋转角,实现「一进多出」——比如同一路摄像头,一路出原图给人看,一路出 300×300 给检测模型。
(3) 零拷贝(dma-buf)。 生产环境里,相机帧和 RGA 输出走的是显存/物理连续内存(dma-buf),而不是 CPU 的普通 malloc 内存。RGA 直接用 importbuffer 把这块物理内存「注册」进来,全程不拷贝数据,延迟和带宽都最优。下面为了演示 API 用虚拟地址,实战请改用 importbuffer_* 系列。
像素格式上最常打交道的几个:
| 格式名 | 含义 | 典型用途 |
|---|---|---|
RK_FORMAT_YCbCr_420_SP |
NV12(YUV420 半平面) | 摄像头/编码器原始输出 |
RK_FORMAT_BGR_888 |
BGR 三平面 | OpenCV / 多数检测模型输入 |
RK_FORMAT_RGB_888 |
RGB 三平面 | 部分模型/显示 |
RK_FORMAT_YCbCr_422_SP |
NV16 | 某些传感器 |
四、实战:C++ 调 librga 做 NV12→RGB + 缩放
Rockchip 的用户态库叫 librga,核心接口在 im2d.h(函数名 imcopy / imresize / imcrop / imrotate / imcvtcolor / improcess)。下面是一段「NV12 转 RGB + 缩放到 300×300」的示意代码:
1 | // 编译需 Rockchip SDK 中的 librga,链接 -lrga |
注意:以上基于
librga的im2d接口示意,具体函数签名与标志位以你所用 SDK 版本的im2d.h为准(不同版本improcess参数略有差异)。生产环境务必用importbuffer_*注册相机/编码器的 dma-buf,而非wrapbuffer_virtualaddr。
为了对照「CPU 方案到底慢在哪」,下面是等价的 Python/OpenCV 实现——它跑在通用 CPU 上:
1 | import cv2, numpy as np, time |
跑起来你会看到:单帧就要近 10 ms,四路并发时四核 CPU 被 cvtColor+resize 占满——而这还只是预处理,没算检测推理。
五、对比总结:RGA 硬件加速 vs CPU 预处理
把四路 1080P、每路 NV12→RGB 并缩放到 300×300 的实测(均来自真实部署经验)摆在一起:
| 维度 | CPU 预处理(OpenCV) | RGA 硬件加速 |
|---|---|---|
| 转换/缩放执行单元 | 通用 CPU 核 | 独立 2D 加速硬件 |
| 四路 1080P CPU 占用 | 接近 100% | 个位数 % |
| 稳定帧率 | ~15 fps | ~30 fps |
| 整板功耗 | 高(CPU 满载发热) | 降约 20% |
| 留给 AI 推理的算力 | 所剩无几 | 充裕 |
| 数据搬运 | 内存拷贝 | dma-buf 零拷贝(生产环境) |
| 适用分辨率 | 低分辨率勉强 | 多路高分辨率流畅 |
一句话本质:相机到检测模型之间那段「格式转换 + 几何变换」,是典型的规则 2D 操作,RGA 用专用硬件把它从 CPU 上卸下来,等于给 AI 推理让出了整条车道。 当你在 RK3588、RV1126 这类带 RGA 的平台上做视觉项目,第一件事就该把预处理流水线迁到 RGA——别让数据搬运,拖死你的检测。
小结:RGA 是 Rockchip 内置的 2D 图像硬件加速单元,专做裁剪/缩放/旋转/格式转换;通过 MPI 把 VI 绑到 RGA 通道即可组成「相机→RGA→检测」流水线;用
librga的im2d接口(如improcess)一次调用完成转换+缩放,生产环境走 dma-buf 零拷贝;相比 OpenCV CPU 方案,四路 1080P 下 CPU 占用从 ~100% 降到个位数、帧率翻倍、功耗降约 20%。

