背景

公司业务需要用到RK3588 的RGA进行图像处理加速,网上搜了下,这方面的资料很少,在此记录下自己从熟悉文档到应用的整个过程,给有相关需求的小伙伴做个参考。

一、什么是RGA

RGA (Raster Graphic Acceleration Unit)是一个独立的2D硬件加速器,可用于加速点/线绘制,执行图像缩放、旋转、格式转换等常见的2D图形操作。

二、RK3588 RGA及代码示例

2.1 从git拉取官方文档及sample示例

git clone https://github.com/airockchip/librga
cd librga


其中 include 是相关头文件,libs是运行库,samples是代码示例。注意:官方demo是有默认的验证源文件,开始前先看下图对应的md文件。

2.2 图像缩放或者放大

本示例代码是在官方resize_demo的基础上进行改动、验证。说明:因为是Debian系统,安装opencv会报错,缺少libjasper库。网上搜了下比较麻烦,本人使用的先在Ubuntu先编译好的opencv库。

代码功能:使用opencv读取本地 1.jpg 图片,调用RGA resize接口进行图片缩小和放大,再使用opencv保存为新的文件。BIG宏定义是用来执行控制放大还缩操作。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "im2d_version.h"
#include "im2d_type.h"
#include "im2d_single.h"
#include "im2d_common.h"
#include "im2d_buffer.h"
#include "RgaUtils.h"
#include "src/utils/utils.h"
#include "./opencv2/core/core.hpp"
#include "./opencv2/highgui/highgui.hpp"using namespace std;
using namespace cv;#define BIG#ifdef BIG
#define RESIZE_WIDTH  1920
#define RESIZE_HEIGHT 1080
#define SCALE_NAME "./scale_1920_1080.jpg"
#else
#define RESIZE_WIDTH  640
#define RESIZE_HEIGHT 480
#define SCALE_NAME "./zoom_640_480.jpg"
#endifint main(int argc, char **argv)
{clock_t t1, t2;t1 = clock();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;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));Mat image, res;image = imread("./1.jpg");if (image.data == nullptr)                     {cout << "图片文件不存在" << endl;}cout << "图像宽为:" << image.cols << "\t高度为:" << image.rows << "\t通道数为:" << image.channels() << endl;src_width = image.cols;src_height = image.rows;src_format = RK_FORMAT_BGR_888;// src_format = RK_FORMAT_RGBA_8888; // RK_FORMAT_YCbCr_420_SPdst_width = RESIZE_WIDTH;dst_height = RESIZE_HEIGHT;dst_format = RK_FORMAT_BGR_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);cout << " src format: " << get_bpp_from_format(src_format) << endl;cout << " dst format: " << get_bpp_from_format(dst_format) << endl;src_buf = (char *)malloc(src_buf_size);dst_buf = (char *)malloc(dst_buf_size);memcpy(src_buf, image.data, src_width * src_height * get_bpp_from_format(src_format));memset(dst_buf, 0x80, dst_buf_size);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!\n");// goto release_buffer;return -1;}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 \n", __LINE__);ret = imresize(src_img, dst_img);if (ret == IM_STATUS_SUCCESS) {printf("imresize running success!\n");} else {printf("running failed, %s\n", imStrError((IM_STATUS)ret));// goto release_buffer;return -1;}t2 = clock();double time_use = (double)(t2 - t1) / CLOCKS_PER_SEC; // 微秒printf("vptdt_init  time_use is [%f] s\n", time_use);res.create(RESIZE_HEIGHT, RESIZE_WIDTH, CV_8UC3);memcpy(res.data, dst_buf, RESIZE_HEIGHT*RESIZE_WIDTH*3);cv::imwrite(SCALE_NAME, res);printf("save picture: [ %s ] success\n", SCALE_NAME);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;return 0;
}

2.2 图像格式转换

本示例代码是在官方cvtcolor_demo的基础上进行改动、验证。

代码功能:

  1. 打开宏定义BGR2NV12 ,使用opencv读取本地1.jpg图片,调用RGA imcvtcolor 接口实现BGR到YUV的转换;
  2. 关闭宏定义BGR2NV12,读取YUV文件,调用RGA imcvtcolor 接口实现YUV到BGR的转换;
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "im2d_version.h"
#include "im2d_type.h"
#include "im2d_single.h"
#include "im2d_common.h"
#include "im2d_buffer.h"
#include "RgaUtils.h"
#include "src/utils/utils.h"
#include "./opencv2/core/core.hpp"
#include "./opencv2/highgui/highgui.hpp"#include "./opencv4/opencv2/opencv.hpp"
using namespace std;
using namespace cv;#define TRANSFER_FILE "./transfer.YUV"
#define RGA_WRITE_FILE "./rga_res.jpg"
#define OPENCV_WRITE_FILE "./opecv_res.jpg"
#define BGR2NV12
// #define OPENCV_TRANSFER
int main(int argc, char **argv)
{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;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));#ifdef BGR2NV12clock_t t1, t2;t1 = clock();Mat image, res;image = imread("./1.jpg");if (image.data == nullptr){cout << "图片文件不存在" << endl;}cout << "图像宽为:" << image.cols << "\t高度为:" << image.rows << "\t通道数为:" << image.channels() << endl;src_width = image.cols;src_height = image.rows;src_format = RK_FORMAT_BGR_888;dst_width = image.cols;dst_height = image.rows;dst_format = RK_FORMAT_YCbCr_420_SP; // NV12cout << " src format: " << get_bpp_from_format(src_format) << endl;cout << " dst format: " << get_bpp_from_format(dst_format) << endl;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);src_buf = (char *)malloc(src_buf_size);dst_buf = (char *)malloc(dst_buf_size);memcpy(src_buf, image.data, src_width * src_height * get_bpp_from_format(src_format));memset(dst_buf, 0x80, dst_buf_size);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!\n");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;}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;}// ret = imcvtcolor(src_img, dst_img, src_format, dst_format, IM_RGB_TO_YUV_BT709_LIMIT);ret = imcvtcolor(src_img, dst_img, src_format, dst_format, IM_RGB_TO_YUV_BT709_LIMIT);if (ret == IM_STATUS_SUCCESS){printf("imcvtcolor running success!\n");}else{printf("imcvtcolo rrunning failed, %s\n", imStrError((IM_STATUS)ret));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;}t2 = clock();double time_use = (double)(t2 - t1) / CLOCKS_PER_SEC; // 微秒printf("imcvtcolo to YUV time_use is [%f] s\n", time_use);FILE *file = fopen(TRANSFER_FILE, "wb+");if (!file){fprintf(stderr, "Could not open %s\n", TRANSFER_FILE);return false;}else{fprintf(stderr, "open %s and write ok\n", TRANSFER_FILE);}fwrite(dst_buf, image.cols * image.rows * get_bpp_from_format(dst_format), 1, file);fclose(file);#elsesrc_width = 1920;src_height = 1080;src_format = RK_FORMAT_YCbCr_420_SP; // NV12
#ifdef OPENCV_TRANSFERcout << " src format: " << get_bpp_from_format(src_format) << endl;src_buf_size = src_width * src_height * get_bpp_from_format(src_format);src_buf = (char *)malloc(src_buf_size);FILE *file = fopen(TRANSFER_FILE, "rb");if (!file){fprintf(stderr, "Could not open %s\n", TRANSFER_FILE);return -EINVAL;}fread(src_buf, src_width * src_height * get_bpp_from_format(src_format), 1, file);fclose(file);cv::Mat yuvNV12, rgb24;yuvNV12.create(src_height * 3 / 2, src_width, CV_8UC1);memcpy(yuvNV12.data, src_buf, src_width*src_height * 3 / 2);// trans to rgb24cv::cvtColor(yuvNV12, rgb24, cv::COLOR_YUV2BGR_NV12);cv::imwrite(OPENCV_WRITE_FILE, rgb24);printf("[OPENCV] save picture: [ %s ] success\n", OPENCV_WRITE_FILE);free(src_buf);src_buf = NULL;
#elseclock_t t1, t2;t1 = clock();dst_width = 1920;dst_height = 1080;dst_format = RK_FORMAT_BGR_888;cout << "src format: " << get_bpp_from_format(src_format) << endl;cout << "dst format: " << get_bpp_from_format(dst_format) << endl;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);src_buf = (char *)malloc(src_buf_size);dst_buf = (char *)malloc(dst_buf_size);FILE *file = fopen(TRANSFER_FILE, "rb");if (!file){fprintf(stderr, "Could not open %s\n", TRANSFER_FILE);return -EINVAL;}fread(src_buf, src_width * src_height * get_bpp_from_format(src_format), 1, file);fclose(file);printf("read src file success!\n");memset(dst_buf, 0x80, dst_buf_size);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!\n");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;}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;}ret = imcvtcolor(src_img, dst_img, src_format, dst_format, IM_YUV_TO_RGB_BT709_LIMIT);if (ret == IM_STATUS_SUCCESS){printf("imcvtcolor running success!\n");}else{printf("imcvtcolo rrunning failed, %s\n", imStrError((IM_STATUS)ret));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;}t2 = clock();double time_use = (double)(t2 - t1) / CLOCKS_PER_SEC; // 微秒printf("imcvtcolo YUV to BGR time_use is [%f] s\n", time_use);Mat rgb24;rgb24.create(src_height, src_width, CV_8UC3);memcpy(rgb24.data, dst_buf, dst_width*dst_height*3);cv::imwrite(RGA_WRITE_FILE, rgb24);printf("[RGA] save picture: [ %s ] success\n", RGA_WRITE_FILE);
#endif // OPENCV_TRANSFER#endifreturn 0;
}

RK3588 RGA 图像操作相关推荐

  1. 【Matlab 控制】矩阵、图像操作基础

    Matlab矩阵.图像操作基础 1. 矩阵操作 计算特征值和特征向量 计算矩阵指数 2. 图像操作 显示单条曲线 显示多条曲线 设置曲线线宽 添加图例 添加x轴y轴标签 添加图像标题 3. 显示结果 ...

  2. OpenCV图像操作的实例(附完整代码)

    OpenCV图像操作的实例 OpenCV图像操作的实例 OpenCV图像操作的实例 #include "opencv2/core.hpp" #include "openc ...

  3. OpenCV图像操作

    OpenCV图像操作 OpenCV图像操作 输入输出 图片 图像的基本操作 访问像素强度值 内存管理和引用计数 原始操作 可视化图像 OpenCV图像操作 输入输出 图片 C ++ 从文件加载图像: ...

  4. python计算机视觉编程——第一章(基本的图像操作和处理)

    第1章 基本的图像操作和处理 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式--save()函数 1.1.2 创建缩略图 1.1.3 复制并粘贴图像区域 1.1.4 调整尺寸和旋转 ...

  5. HT for Web基于HTML5的图像操作(三)

    上篇采用了HTML5的Canvas的globalCompositeOperation属性达到了染色效果,其实CSS也提供了一些常规图像变化的设置参数,关于CSS的过滤器Filter设置可参考 http ...

  6. python计算机视觉编程——基本的图像操作和处理

    python计算机视觉编程--第一章(基本的图像操作和处理) 第1章 基本的图像操作和处理 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式--save()函数 1.1.2 创建缩略 ...

  7. python-基本的图像操作和处理

    python-基本的图像操作和处理 本章讲解操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的 Python 工具包,并介绍用于读取图像.图像转换和缩放.计算导数.画图和保存结果等的基本工具. ...

  8. 计算机视觉编程——基本的图像操作和处理

    文章目录 基本的图像操作和处理 1 Python图像处理类库 1.1 转换图像格式 1.2 创建缩略图 1.3 复制和粘贴图像区域 1.4 调整尺寸和旋转 2 Matplotlib 2.1 绘制图像. ...

  9. Python计算机视觉编程第1章基本的图像操作和处理

    目录 第 1 章 基本的图像操作和处理 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式 1.1.2 创建缩略图 1.2 Matplotlib 1.2.1 绘制图像.点和线 1.2. ...

最新文章

  1. 使用python手写FFT算法
  2. 一起谈.NET技术,也玩MVC3.0 Razor自定义视图引擎来修改默认的Views目录结构
  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(42)-工作流设计-表建立
  4. 为什么单片机程序中会有延时程序加入
  5. java 国际化例子_JavaSE 国际化 简单例子
  6. 【Linux】40.date设定系统时间
  7. Hive的基本操作-创建内部表
  8. Java案例:静态内部类
  9. python 删除文件夹_Python文件操作大全,随机删除文件夹内的任意文件
  10. Apple 宣布 2021 年 Apple Design Awards 获奖者
  11. OpenLayers使用高德导航接口实现动画animate
  12. 2022程序员都推荐的算法编程课程终于来了!新手从入门到面试考点全覆盖,学到就是赚到!...
  13. Babel 是什么?· Babel 中文文档
  14. win11无法安装msi程序的解决方法
  15. nginx启动无反应
  16. 送书 | 哈佛大学单细胞课程:笔记汇总前篇
  17. biti_rainy的blog
  18. linux 中.a和.so的区别
  19. 面试感悟----一名3年工作经验的程序员应该具备的技能,对于一些入门或者还在面试阶段的人有着很大的启发...
  20. 软件著作权和专利的区别

热门文章

  1. 如果iPhone被标记被盗或丢失 苹果将拒绝维修
  2. IC617 PDK CDB格式转OA格式
  3. Mac快捷键及手势基本操作
  4. 冯诺依曼原理奠定了至今仍然在使用的计算机,计算机二级MS-Office真题「选择题」...
  5. 一文告诉你数据安全平台(DSP)能做什么
  6. css淡入淡出_CSS淡入淡出
  7. 关于BIOS升级的方法
  8. python概率编程_Python概率编程库PyMC应用案例二则,pymc应用案例
  9. 数字图像处理:python对图像做傅里叶变换,理想低通滤波器,理想高通滤波器
  10. 系统如何自动识别短信验证码