查看: 797|回复: 0

在i.MX RT处理器上使用PXP实现缩放和旋转组合操作

[复制链接]
  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3930

    主题

    7550

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    40091
    最后登录
    2025-8-29
    发表于 2025-2-20 09:28:49 | 显示全部楼层 |阅读模式
    本文主要探讨如何使用PXP实现缩放和旋转组合操作,PXP是NXP推出的一个2D图形加速器,主要完成对图像的数据格式转换、固定角度旋转(90°,180°,270°),任意比例缩放、混色,移位以及翻转等功能。运行平台为i.MX RT1170/1160/1060/1050/1040。


    其功能结构框如下图所示:
    12.png
    其工作域有3个:PS, AS以及OUTPUT。


    PS域和AS域是输入域,如果不需要混色,就只需要PS域输入就可以了。PS域的输入图像可以进行缩放、颜色转换以及旋转等操作。


    本文主要讨论一种特殊的情况,经过PS域,先进行缩放再进行旋转,然后输出。比如摄像头输入一个640(w)* 480(h)的图片,经过放大和旋转后,输出到一个720(w)*1280(h)的屏幕上。这个转换过程如下图所示:
    13.png
    为了实现这个操作,我们需要配置一个PS域的区域范围,对于这种场景,PS域的范围应该配置为(0,0,1280-1,1280-1),这四个坐标分别表示区域的左上角x,左上角y,右下角x,右下角y。上面的图形在PS域中的位置如下图所示:
    14.png
    这样,通过把PS域的大小配置为1280*1280的正方形,才能保证图像在放大和旋转完的过程中,所有的输入和输出都在PS域的范围内。超过PS域的范围,PXP不保证里面的数据正确,这一点在配置PXP的时候非常重要。另外PXP的框图结构里面有两个旋转(Rotation)单元。对于要依次做缩放和旋转的情况,需要使用PXP的第二个旋转单元。


    下面我们从代码层面看一看相关的配置:


    1.定义屏幕尺寸和原始图像尺寸

    1. #define APP_PANEL_WIDTH  720

    2. #define APP_PANEL_HEIGHT 1280

    3. #define APP_IMG_SIZE_W 640

    4. #define APP_IMG_SIZE_H 480
    复制代码
    2. PS域的配置
    下面的代码是PS输入图像的buffer的相关配置。
    这里重点讲一下pitchBytes的概念。pitchBytes是用来指定一行图像的字节数,它等于一行数据的像素数*每个像素的字节数。PXP是靠这个参数来作为输入数据的换行边界。

    1. const pxp_ps_buffer_config_tpsBufferConfig = {

    2. .pixelFormat = APP_PXP_PS_FORMAT,

    3. .swapByte    = false,

    4. .bufferAddr  = (uint32_t)s_psBufferPxp,  // PS input image buffer

    5. .bufferAddrU = 0U,

    6. .bufferAddrV = 0U,

    7. .pitchBytes  = APP_IMG_SIZE_W * APP_BPP,

    8. };
    复制代码
    配置PS区域,需要配置为配置为(0,0,1280-1,1280-1)。

    1. PXP_SetProcessSurfacePosition(

    2. APP_PXP,

    3. 0,

    4. 0,

    5. APP_PANEL_HEIGHT-1,  // 1280-1

    6. APP_PANEL_HEIGHT-1);// 1280-1
    复制代码
    3.配置输出buffer
    这里需要注意,当使用第二级的旋转单元时,我们配置的输出区域的长和宽是旋转之前的长度和宽度,这一点非常容易出错。而pitchBytes一般都会配成旋转后的图像宽度(像素数)* 每个像素的字节数。
    1. outputBufferConfig.pixelFormat    = APP_PXP_OUT_FORMAT;

    2. outputBufferConfig.interlacedMode = kPXP_OutputProgressive;

    3. outputBufferConfig.buffer0Addr    = (uint32_t)s_BufferLcd[0];

    4. outputBufferConfig.buffer1Addr    = 0U;

    5. outputBufferConfig.pitchBytes     = APP_PANEL_WIDTH * APP_BPP;

    6. outputBufferConfig.width          = APP_PANEL_HEIGHT; //1280;

    7. outputBufferConfig.height         = APP_PANEL_WIDTH;  //720;
    复制代码
    4.配置缩放比例和旋转角度
    这里缩放比例是通过缩放前的长宽和缩放后的长宽来指定的,API内部会自动计算缩放系数。

    1. PXP_SetProcessSurfaceScaler(APP_PXP,

    2. APP_IMG_SIZE_W,

    3. APP_IMG_SIZE_H,

    4. APP_PANEL_HEIGHT,

    5. APP_PANEL_WIDTH);
    复制代码

    1. PXP_SetRotateConfig(APP_PXP,

    2. kPXP_RotateOutputBuffer,  // Use the 2nd rotation unit.

    3. kPXP_Rotate90,

    4. kPXP_FlipDisable);
    复制代码
    运行结果如下,左边是原始图像,右边是放大以及旋转90°得到的图像:
    15.png







    qiandao qiandao
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-31 21:06 , Processed in 0.078877 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表