RK3588-Linux-RGA使用教程(无脑运行就完事)
1.前言
RGA (Raster Graphic Acceleration Unit)是一个独立的2D硬件加速器,可用于加速点/线绘制,执行图像缩放、旋转、bitBlt、alpha混合等常见的2D图形操作。环境都配好了,直接使用
2. 准备
(1)查看驱动版本
cat /sys/kernel/debug/rkrga/driver_version

(2) 下载rga测试代码
GitHub - TRQ-UP/Rk3588-linux-rga: rk3588-linux使用rga
3.代码讲解
(1)CMakeList文件
后续rga或者opencv的更新版本,直接放到3rdparty文件夹中,在cmakelist中配置一下
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(${NCNN_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)main代码
代码中只展示了部分的api功能,完整的功能请参考RGA IM2D API 开发指南
使用rga的基本步骤
(1)定义图像缓冲区的描述结构体(如rga_buffer_t)。
(2)初始化这些结构体(通常通过memset清零)。
(3)创建或获取图像缓冲区的句柄(如rga_buffer_handle_t)。
(4)使用这些结构体和句柄进行图像处理操作(如缩放、旋转、格式转换等
#include "opencv2/opencv.hpp"
#include
#include "im2d_version.h"
#include "im2d_type.h"
#include "im2d_single.h"
#include "im2d_common.h"
#include "im2d_buffer.h"
#include "RgaUtils.h"
using namespace std;
const char* querystring(int name);
/*RGA_VENDOR - 厂商信息
RGA_VERSION - 版本信息
RGA_MAX_INPUT - 支持的最大输入分辨率
RGA_MAX_OUTPUT - 支持的最大输出分辨率
RGA_SCALE_LIMIT - 支持得缩放倍数
RGA_INPUT_FORMAT - 支持的输入格式
RGA_OUTPUT_FORMAT - 支持的输出格式
RGA_EXPECTED - 预期性能
RGA_ALL - 输出所有信息*/
void print_rga_info() {
// cout << querystring(RGA_VENDOR) << endl;
// cout << querystring(RGA_VERSION) << endl;
// cout << querystring(RGA_MAX_INPUT) << endl;
// cout << querystring(RGA_MAX_OUTPUT) << endl;
// cout << querystring(RGA_SCALE_LIMIT) << endl;
// cout << querystring(RGA_INPUT_FORMAT) << endl;
// cout << querystring(RGA_OUTPUT_FORMAT ) << endl;
// cout << querystring(RGA_EXPECTED ) << endl;
cout << querystring(RGA_ALL) << endl;
}
int main(int argc, char **argv) {
// 输出rga的信息
print_rga_info();
//设置图像类型
int ret = 0;
// 原始图片的宽、高、格式
int src_width, src_height, src_format;
// 目标图片的宽、高、格式
int dst_width, dst_height, dst_format;
// 缓冲区(用于暂存输入或输出的数据,从而减少系统调用的次数)
char *src_buf, *dst_buf;
// 图像缓冲区大小
int src_buf_size, dst_buf_size;
/*1.基本步骤:使用硬件加速(如RGA)进行图像处理的程序中。在使用RGA或其他类似的硬件加速库时,通常需要:
(1)定义图像缓冲区的描述结构体(如rga_buffer_t)。
(2)初始化这些结构体(通常通过memset清零)。
(3)创建或获取图像缓冲区的句柄(如rga_buffer_handle_t)。
(4)使用这些结构体和句柄进行图像处理操作(如缩放、旋转、格式转换等
*2.rga_buffer_t:结构体类型,用于描述图像缓冲区的属性(如宽度、高度、格式、内存地址等)。
src_img 和 dst_img:这两个变量分别表示源图像和目标图像的缓冲区描述。
rga_buffer_handle_t:这是一个句柄类型,通常用于引用图像缓冲区(可能是指向rga_buffer_t的指针或其他形式的句柄)。
src_handle 和 dst_handle:这两个变量分别表示源图像和目标图像的缓冲区句柄。*/
// 描述源图像和目标图像的缓冲区属性
rga_buffer_t src_img, dst_img;
// 引用图像缓冲区
rga_buffer_handle_t src_handle, dst_handle;
// 初始化结构体变量
memset(&src_img, 0, sizeof(src_img));
memset(&dst_img, 0, sizeof(dst_img));
// 使用opencv读取图片
cv::Mat image, res;
image = cv::imread("../img/test.jpg");
// cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
if (image.data == nullptr)
{
cout << "图片文件不存在" << endl;
}
cout << "图像宽为:" << image.cols << " 高度为:" << image.rows << " 通道数为:" << image.channels() << endl;
cv::Mat opncv_resize;
cv::resize(image, opncv_resize,cv::Size(1920,1080));
cv::imwrite("../img/opencv_rezie.jpg", opncv_resize);
// 设置源图像的宽度、高度和格式
src_width = image.cols;
src_height = image.rows;
src_format = RK_FORMAT_RGB_888;
// 设置目标图像的宽度、高度和格式
dst_width = 1920;
dst_height = 1080;
// dst_width = image.cols;
// dst_height = image.rows;
dst_format = RK_FORMAT_RGB_888;
// 计算源图像和目标图像的缓冲区大小(基于宽度、高度和每个像素位数)。
src_buf_size = src_width * src_height * get_bpp_from_format(src_format);
dst_buf_size = dst_width * dst_height * get_bpp_from_format(dst_format);
// 使用malloc分配内存给源图像和目标图像的缓冲区。
src_buf = (char *) malloc(src_buf_size);
dst_buf = (char *)malloc(dst_buf_size);
cout << " src format: " << get_bpp_from_format(src_format) << endl;
cout << " dst format: " << get_bpp_from_format(dst_format) << endl;
// 将源图像数据从OpenCV的cv::Mat对象复制到自定义的缓冲区src_buf中
memcpy(src_buf, image.data, src_width * src_height * get_bpp_from_format(src_format));
memset(dst_buf, 0x80, dst_buf_size);
// 使用importbuffer_virtualaddr将源图像和目标图像的缓冲区导入为RGA可识别的句柄
src_handle = importbuffer_virtualaddr(src_buf, src_buf_size);
dst_handle = importbuffer_virtualaddr(dst_buf, dst_buf_size);
if (src_handle == 0 || dst_handle == 0) {
printf("importbuffer failed!
");
// goto release_buffer;
return -1;
}
// 使用wrapbuffer_handle将句柄包装为rga_buffer_t结构体,包含图像的宽度、高度和格式信息。
src_img = wrapbuffer_handle(src_handle, src_width, src_height, src_format);
dst_img = wrapbuffer_handle(dst_handle, dst_width, dst_height, dst_format);
// 检查图像
ret = imcheck(src_img, dst_img, {}, {});
if (IM_STATUS_NOERROR != ret) {
printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
return -1;
}
printf("%d, check success
", __LINE__);
// 图像缩放
// ret = imresize(src_img, dst_img);
// 图像旋转
// ret = imrotate(src_img, dst_img, 180);
/* 图像裁剪
im_rect的结构体,用于描述图像区域*/
// im_rect region;
// region.x = 10;
// region.y = 10;
// region.width = 100;
// region.height = 100;
// ret = imcrop(src_img, dst_img, region);
/*图片镜像
* 0:不变
* IM_HAL_TRANSFORM_FLIP_H:左右翻转
* IM_HAL_TRANSFORM_FLIP_V:上下翻转 */
ret = imflip(src_img, dst_img, 0);
if (ret == IM_STATUS_SUCCESS) {
printf("imresize running success!
");
} else {
printf("running failed, %s
", imStrError((IM_STATUS)ret));
// goto release_buffer;
return -1;
}
// 将rk格式的图片转成opencv识别的图片格式并保存
res.create(dst_height, dst_width, CV_8UC3);
memcpy(res.data, dst_buf, dst_height*dst_width*3);
cv::imwrite("../img/result.jpg", res);
printf("save picture: [ %s ] success
", "../img/result.jpg");
// 释放资源
release_buffer:
if (src_handle)
releasebuffer_handle(src_handle);
if (dst_handle)
releasebuffer_handle(dst_handle);
if (src_buf)
free(src_buf);
if (dst_buf)
free(dst_buf);
return ret;
}
4.结果展示
|
原始图片 |
|
opencv-reszie |
|
rga-resize |














