Skip to main content

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;
}