在i.MX RT处理器上使用PXP实现缩放和旋转组合操作
本文主要探讨如何使用PXP实现缩放和旋转组合操作,PXP是NXP推出的一个2D图形加速器,主要完成对图像的数据格式转换、固定角度旋转(90°,180°,270°),任意比例缩放、混色,移位以及翻转等功能。运行平台为i.MX RT1170/1160/1060/1050/1040。
本文引用地址:https://www.eepw.com.cn/article/202502/467295.htm其功能结构框如下图所示:
其工作域有3个:PS, AS以及OUTPUT。
PS域和AS域是输入域,如果不需要混色,就只需要PS域输入就可以了。PS域的输入图像可以进行缩放、颜色转换以及旋转等操作。
本文主要讨论一种特殊的情况,经过PS域,先进行缩放再进行旋转,然后输出。比如摄像头输入一个640(w)* 480(h)的图片,经过放大和旋转后,输出到一个720(w)*1280(h)的屏幕上。这个转换过程如下图所示:
为了实现这个操作,我们需要配置一个PS域的区域范围,对于这种场景,PS域的范围应该配置为(0,0,1280-1,1280-1),这四个坐标分别表示区域的左上角x,左上角y,右下角x,右下角y。上面的图形在PS域中的位置如下图所示:
这样,通过把PS域的大小配置为1280*1280的正方形,才能保证图像在放大和旋转完的过程中,所有的输入和输出都在PS域的范围内。超过PS域的范围,PXP不保证里面的数据正确,这一点在配置PXP的时候非常重要。另外PXP的框图结构里面有两个旋转(Rotation)单元。对于要依次做缩放和旋转的情况,需要使用PXP的第二个旋转单元。
下面我们从代码层面看一看相关的配置:
1.定义屏幕尺寸和原始图像尺寸
#define APP_PANEL_WIDTH 720 #define APP_PANEL_HEIGHT 1280 #define APP_IMG_SIZE_W 640 #define APP_IMG_SIZE_H 480
2. PS域的配置下面的代码是PS输入图像的buffer的相关配置。
这里重点讲一下pitchBytes的概念。pitchBytes是用来指定一行图像的字节数,它等于一行数据的像素数*每个像素的字节数。PXP是靠这个参数来作为输入数据的换行边界。
const pxp_ps_buffer_config_tpsBufferConfig = { .pixelFormat = APP_PXP_PS_FORMAT, .swapByte = false, .bufferAddr = (uint32_t)s_psBufferPxp, // PS input image buffer .bufferAddrU = 0U, .bufferAddrV = 0U, .pitchBytes = APP_IMG_SIZE_W * APP_BPP, };
配置PS区域,需要配置为配置为(0,0,1280-1,1280-1)。
PXP_SetProcessSurfacePosition( APP_PXP, 0, 0, APP_PANEL_HEIGHT-1, // 1280-1 APP_PANEL_HEIGHT-1);// 1280-1
3.配置输出buffer
这里需要注意,当使用第二级的旋转单元时,我们配置的输出区域的长和宽是旋转之前的长度和宽度,这一点非常容易出错。而pitchBytes一般都会配成旋转后的图像宽度(像素数)* 每个像素的字节数。
outputBufferConfig.pixelFormat = APP_PXP_OUT_FORMAT; outputBufferConfig.interlacedMode = kPXP_OutputProgressive; outputBufferConfig.buffer0Addr = (uint32_t)s_BufferLcd[0]; outputBufferConfig.buffer1Addr = 0U; outputBufferConfig.pitchBytes = APP_PANEL_WIDTH * APP_BPP; outputBufferConfig.width = APP_PANEL_HEIGHT; //1280; outputBufferConfig.height = APP_PANEL_WIDTH; //720;
4.配置缩放比例和旋转角度
这里缩放比例是通过缩放前的长宽和缩放后的长宽来指定的,API内部会自动计算缩放系数。
PXP_SetProcessSurfaceScaler(APP_PXP, APP_IMG_SIZE_W, APP_IMG_SIZE_H, APP_PANEL_HEIGHT, APP_PANEL_WIDTH);
PXP_SetRotateConfig(APP_PXP, kPXP_RotateOutputBuffer, // Use the 2nd rotation unit. kPXP_Rotate90, kPXP_FlipDisable);
运行结果如下,左边是原始图像,右边是放大以及旋转90°得到的图像:
评论