概述
RGA (Raster Graphic Acceleration Unit) 是一个独立的 2D 硬件加速器,可用于加速点/线绘制,执行图像缩放、旋转、bitBlt、alpha 混合等常见的 2D 图形操作。假设驱动环境已就绪,可直接使用。
环境准备
1. 查看驱动版本
cat /sys/kernel/debug/rkrga/driver_version
2. 下载测试代码
参考 GitHub 仓库:TRQ-UP/Rk3588-linux-rga
代码实现
1. CMakeLists.txt 配置
后续 RGA 或 OpenCV 的更新版本,直接放到 3rdparty 文件夹中,在 CMakeLists 中配置即可。
cmake_minimum_required(VERSION 3.16)
project(opencv_411_test)
set(CMAKE_CXX_STANDARD 11)
# 设置库架构
set(LIB_ARCH "aarch64")
set(DEVICE_NAME "RK3588")
# 设置 OpenCV 路径
set(OpenCV_DIR ./3rdparty/opencv/opencv-linux-aarch64/share/OpenCV)
find_package(OpenCV REQUIRED)
# 输出 OpenCV 信息
message(STATUS "OpenCV include dirs: ${OpenCV_INCLUDE_DIRS}")
message(STATUS "Found OpenCV Version: ${OpenCV_VERSION}")
set(3RDPARTY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty)
# 设置 RGA 的路径
set(RGA_DIR ${3RDPARTY_PATH}/rga/${DEVICE_NAME})
set(RGA_LIB ${RGA_DIR}/lib/Linux/${LIB_ARCH}/librga.so)
# 用来搜索头文件的目录
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${RGA_DIR}/include)
# 编译源代码
add_executable(opencv_411_test src/main.cpp)
# 链接 OpenCV 和 RGA 库
target_link_libraries(opencv_411_test ${OpenCV_LIBS} ${RGA_LIB})
2. 主程序逻辑
完整功能请参考 RGA IM2D API 开发指南。
使用 RGA 的基本步骤:
- 定义图像缓冲区的描述结构体(如
rga_buffer_t)。 - 初始化这些结构体(通常通过
memset清零)。 - 创建或获取图像缓冲区的句柄(如
rga_buffer_handle_t)。 - 使用这些结构体和句柄进行图像处理操作(如缩放、旋转、格式转换等)。
#include "opencv2/opencv.hpp"
#include <iostream>
#include "im2d_version.h"
#include "im2d_type.h"
std;
;
{
cout << (RGA_ALL) << endl;
}
{
();
ret = ;
src_width, src_height, src_format;
dst_width, dst_height, dst_format;
*src_buf, *dst_buf;
src_buf_size, dst_buf_size;
src_img, dst_img;
src_handle, dst_handle;
(&src_img, , (src_img));
(&dst_img, , (dst_img));
cv::Mat image, res;
image = cv::();
(image.data == ) {
cout << << endl;
;
}
cout << << image.cols << << image.rows << << image.() << endl;
cv::Mat opencv_resize;
cv::(image, opencv_resize, cv::(, ));
cv::(, opencv_resize);
src_width = image.cols;
src_height = image.rows;
src_format = RK_FORMAT_RGB_888;
dst_width = ;
dst_height = ;
dst_format = RK_FORMAT_RGB_888;
src_buf_size = src_width * src_height * (src_format);
dst_buf_size = dst_width * dst_height * (dst_format);
src_buf = ( *)(src_buf_size);
dst_buf = ( *)(dst_buf_size);
cout << << (src_format) << endl;
cout << << (dst_format) << endl;
(src_buf, image.data, src_width * src_height * (src_format));
(dst_buf, , dst_buf_size);
src_handle = (src_buf, src_buf_size);
dst_handle = (dst_buf, dst_buf_size);
(src_handle == || dst_handle == ) {
();
;
}
src_img = (src_handle, src_width, src_height, src_format);
dst_img = (dst_handle, dst_width, dst_height, dst_format);
ret = (src_img, dst_img, {}, {});
(IM_STATUS_NOERROR != ret) {
(, __LINE__, ((IM_STATUS)ret));
;
}
(, __LINE__);
ret = (src_img, dst_img, );
(ret == IM_STATUS_SUCCESS) {
();
} {
(, ((IM_STATUS)ret));
;
}
res.(dst_height, dst_width, CV_8UC3);
(res.data, dst_buf, dst_height * dst_width * );
cv::(, res);
(, );
release_buffer:
(src_handle) (src_handle);
(dst_handle) (dst_handle);
(src_buf) (src_buf);
(dst_buf) (dst_buf);
ret;
}


