在i.MX RT處理器上使用PXP實(shí)現(xiàn)縮放和旋轉(zhuǎn)組合操作
本文主要探討如何使用PXP實(shí)現(xiàn)縮放和旋轉(zhuǎn)組合操作,PXP是NXP推出的一個(gè)2D圖形加速器,主要完成對(duì)圖像的數(shù)據(jù)格式轉(zhuǎn)換、固定角度旋轉(zhuǎn)(90°,180°,270°),任意比例縮放、混色,移位以及翻轉(zhuǎn)等功能。運(yùn)行平臺(tái)為i.MX RT1170/1160/1060/1050/1040。
本文引用地址:http://m.butianyuan.cn/article/202502/467295.htm其功能結(jié)構(gòu)框如下圖所示:
其工作域有3個(gè):PS, AS以及OUTPUT。
PS域和AS域是輸入域,如果不需要混色,就只需要PS域輸入就可以了。PS域的輸入圖像可以進(jìn)行縮放、顏色轉(zhuǎn)換以及旋轉(zhuǎn)等操作。
本文主要討論一種特殊的情況,經(jīng)過(guò)PS域,先進(jìn)行縮放再進(jìn)行旋轉(zhuǎn),然后輸出。比如攝像頭輸入一個(gè)640(w)* 480(h)的圖片,經(jīng)過(guò)放大和旋轉(zhuǎn)后,輸出到一個(gè)720(w)*1280(h)的屏幕上。這個(gè)轉(zhuǎn)換過(guò)程如下圖所示:
為了實(shí)現(xiàn)這個(gè)操作,我們需要配置一個(gè)PS域的區(qū)域范圍,對(duì)于這種場(chǎng)景,PS域的范圍應(yīng)該配置為(0,0,1280-1,1280-1),這四個(gè)坐標(biāo)分別表示區(qū)域的左上角x,左上角y,右下角x,右下角y。上面的圖形在PS域中的位置如下圖所示:
這樣,通過(guò)把PS域的大小配置為1280*1280的正方形,才能保證圖像在放大和旋轉(zhuǎn)完的過(guò)程中,所有的輸入和輸出都在PS域的范圍內(nèi)。超過(guò)PS域的范圍,PXP不保證里面的數(shù)據(jù)正確,這一點(diǎn)在配置PXP的時(shí)候非常重要。另外PXP的框圖結(jié)構(gòu)里面有兩個(gè)旋轉(zhuǎn)(Rotation)單元。對(duì)于要依次做縮放和旋轉(zhuǎn)的情況,需要使用PXP的第二個(gè)旋轉(zhuǎn)單元。
下面我們從代碼層面看一看相關(guān)的配置:
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的相關(guān)配置。
這里重點(diǎn)講一下pitchBytes的概念。pitchBytes是用來(lái)指定一行圖像的字節(jié)數(shù),它等于一行數(shù)據(jù)的像素?cái)?shù)*每個(gè)像素的字節(jié)數(shù)。PXP是靠這個(gè)參數(shù)來(lái)作為輸入數(shù)據(jù)的換行邊界。
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區(qū)域,需要配置為配置為(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
這里需要注意,當(dāng)使用第二級(jí)的旋轉(zhuǎn)單元時(shí),我們配置的輸出區(qū)域的長(zhǎng)和寬是旋轉(zhuǎn)之前的長(zhǎng)度和寬度,這一點(diǎn)非常容易出錯(cuò)。而pitchBytes一般都會(huì)配成旋轉(zhuǎn)后的圖像寬度(像素?cái)?shù))* 每個(gè)像素的字節(jié)數(shù)。
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.配置縮放比例和旋轉(zhuǎn)角度
這里縮放比例是通過(guò)縮放前的長(zhǎng)寬和縮放后的長(zhǎng)寬來(lái)指定的,API內(nèi)部會(huì)自動(dòng)計(jì)算縮放系數(shù)。
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);
運(yùn)行結(jié)果如下,左邊是原始圖像,右邊是放大以及旋轉(zhuǎn)90°得到的圖像:
評(píng)論