1. RGA 图像缩放示例
本示例演示了如何在 Rockchip 平台 上使用 RGA(Raster Graphic Accelerator)硬件加速模块 实现高性能的图像缩放(resize)操作。
与基于 CPU 的 OpenCV 缩放函数相比,RGA 可通过硬件加速实现更低的 CPU 占用率和更高的处理速度,非常适合嵌入式平台( RK3588 / RK3576)进行实时图像处理任务。
本示例支持 OpenCV 图像读写,从而更方便地与常见计算机视觉项目结合。
2. 主要功能
- 使用 OpenCV 读取输入图像(JPEG、PNG、BMP 等);
- 自动将图像转换为 RGA 支持的 RGBA8888 格式;
- 使用 RGA 硬件加速接口 实现图像缩放;
- 将结果图像保存为
output_rga_resize.png.
3. 代码结构与执行流程
3.1 图像读取与格式转换
Mat src = imread(image_path, IMREAD_UNCHANGED);
if (src.channels() == 3)
cvtColor(src, src, COLOR_BGR2RGBA);
else if (src.channels() == 1)
cvtColor(src, src, COLOR_GRAY2RGBA);
- 使用 cv::imread() 加载任意输入图像;
- 将图像转换为 RGBA 格式(RGA 默认支持的输入格式为 RK_FORMAT_RGBA_8888)。
3.2 创建目标图像缓冲区
int dst_width = 1920;
int dst_height = 1080;
Mat dst(dst_height, dst_width, CV_8UC4, Scalar(0, 0, 0, 255));
- 创建目标图像,分辨率为 1920×1080;
- 图像格式为 RGBA;
- 用于存放 RGA 缩放后的输出结果。
3.3 导入 RGA 缓冲区
rga_buffer_handle_t src_handle = importbuffer_virtualaddr(src.data, src.total() * src.elemSize());
rga_buffer_handle_t dst_handle = importbuffer_virtualaddr(dst.data, dst.total() * dst.elemSize());
- 使用 importbuffer_virtualaddr() 将 OpenCV 图像内存导入为 RGA 可识别的缓冲区;
- 使用 wrapbuffer_handle() 封装为 rga_buffer_t 结构。
3.4 调用 RGA 进行图像缩放
ret = imcheck(src_img, dst_img, {}, {});
ret = imresize(src_img, dst_img);
- imcheck():检查输入输出图像格式、尺寸是否合法;
- imresize():调用 RGA 的硬件接口执行缩放;
- 若返回 IM_STATUS_SUCCESS,则表示执行成功。
3.5 保存结果图像
cvtColor(dst, dst, COLOR_RGBA2BGR);
imwrite("output_rga_resize.png", dst);
- 将结果图像从 RGBA 转回 BGR;
- 使用 cv::imwrite() 输出到文件 output_rga_resize.png。
3.6 释放资源
releasebuffer_handle(src_handle);
releasebuffer_handle(dst_handle);
释放 RGA 缓冲区句柄,避免内存泄漏。
4. 编译与运行
4.1 环境依赖
- 确保OpenCV有安装, 或者使用如下命令安装OpenCV
sudo apt install libopencv-dev
- 确保librga有安装, Neardi设备出厂时固件都包含librga
4.2 编译命令
g++ main.cpp -o rga_resize_demo \
-I/usr/include/rga -I/usr/include/opencv4 \
-lrga -lopencv_core -lopencv_imgcodecs -lopencv_imgproc
编译成功后, 有如下文件:
.
├── build.sh
├── main.cpp
├── rga_resize_opencv
└── test.jpg
4.3 运行
执行如下命令:
linaro@linaro-alip:~/librga/src$ ./rga_resize_opencv test.jpg
rga_api version 1.10.1_[10]
rga_resize_demo running success!
Saved output to output_rga_resize.png
linaro@linaro-alip:~/librga/src$ ls
build.sh main.cpp output_rga_resize.png rga_resize_opencv test.jpg
执行后将在当前目录生成:
output_rga_resize.png
4.4 运行结果
- 输入图像:任意分辨率的 JPEG/PNG 文件;
- 输出图像:缩放为 1920×1080 的 PNG;
- 输出文件名:output_rga_resize.png。
5. 小结
本示例展示了 RGA + OpenCV 的联合使用方式,实现了简洁、高效的图像缩放流程。 基于此框架,可进一步扩展 RGA 的其他功能,包括:
- 图像旋转与镜像;
- 颜色空间转换;
- 多图层合成(Overlay);
- 图像裁剪(Crop)。
整体代码如下:
#define LOG_NDEBUG 0
#undef LOG_TAG
#define LOG_TAG "rga_resize_demo"
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <rga/RgaApi.h>
#include <rga/RgaUtils.h>
#include <rga/im2d.hpp>
using namespace cv;
using namespace std;
int main(int argc, char **argv) {
if (argc != 2) {
printf("Usage: %s <input_image>\n", argv[0]);
return -1;
}
const char *image_path = argv[1];
int ret = 0;
// ------------------------------
// 1. 使用 OpenCV 读取源图像
// ------------------------------
Mat src = imread(image_path, IMREAD_UNCHANGED);
if (src.empty()) {
cerr << "Failed to load image: " << image_path << endl;
return -1;
}
// 转换为 RGBA(RGA 期望格式)
if (src.channels() == 3)
cvtColor(src, src, COLOR_BGR2RGBA);
else if (src.channels() == 1)
cvtColor(src, src, COLOR_GRAY2RGBA);
int src_width = src.cols;
int src_height = src.rows;
int src_format = RK_FORMAT_RGBA_8888;
// ------------------------------
// 2. 创建目标图像
// ------------------------------
int dst_width = 1920;
int dst_height = 1080;
int dst_format = RK_FORMAT_RGBA_8888;
Mat dst(dst_height, dst_width, CV_8UC4, Scalar(0, 0, 0, 255));
// ------------------------------
// 3. 申请并导入 RGA 缓冲区
// ------------------------------
rga_buffer_handle_t src_handle = importbuffer_virtualaddr(src.data, src.total() * src.elemSize());
rga_buffer_handle_t dst_handle = importbuffer_virtualaddr(dst.data, dst.total() * dst.elemSize());
if (src_handle == 0 || dst_handle == 0) {
cerr << "importbuffer failed!" << endl;
return -1;
}
rga_buffer_t src_img = wrapbuffer_handle(src_handle, src_width, src_height, src_format);
rga_buffer_t dst_img = wrapbuffer_handle(dst_handle, dst_width, dst_height, dst_format);
// ------------------------------
// 4. 调用 RGA 进行缩放
// ------------------------------
ret = imcheck(src_img, dst_img, {}, {});
if (IM_STATUS_NOERROR != ret) {
cerr << "Check error: " << imStrError((IM_STATUS)ret) << endl;
return -1;
}
ret = imresize(src_img, dst_img);
if (ret == IM_STATUS_SUCCESS) {
cout << LOG_TAG << " running success!" << endl;
} else {
cerr << LOG_TAG << " running failed: " << imStrError((IM_STATUS)ret) << endl;
return -1;
}
// ------------------------------
// 5. 使用 OpenCV 保存结果图像
// ------------------------------
cvtColor(dst, dst, COLOR_RGBA2BGR);
imwrite("output_rga_resize.png", dst);
cout << "Saved output to output_rga_resize.png" << endl;
if (src_handle)
releasebuffer_handle(src_handle);
if (dst_handle)
releasebuffer_handle(dst_handle);
return ret;
}