在i.MX RT處理器上使用PXP實現縮放和旋轉組合操作
本文主要探討如何使用PXP實現縮放和旋轉組合操作,PXP是NXP推出的一個2D圖形加速器,主要完成對圖像的數據格式轉換、固定角度旋轉(90°,180°,270°),任意比例縮放、混色,移位以及翻轉等功能。運行平臺為i.MX RT1170/1160/1060/1050/1040。
本文引用地址:http://www.104case.com/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°得到的圖像:
評論