【2023 · CANN訓(xùn)練營(yíng)第一季】數(shù)據(jù)預(yù)處理-VPC圖片縮放
文檔參考:CANN文檔社區(qū)版: 6.0.RC1.alpha001
一、VPC相關(guān)接口簡(jiǎn)介
ACL接口中的VPC相關(guān)接口:主要負(fù)責(zé)圖像處理功能,支持對(duì)圖片做摳圖、縮放、疊加、拼接、格式轉(zhuǎn)換等操作
還是和JPEGD一樣,我們?cè)谑褂眠^(guò)程中,簡(jiǎn)單了解功能后,最先注意的應(yīng)該是其性能指標(biāo),以保證我們不會(huì)在非正常指標(biāo)的情況下進(jìn)行相關(guān)代碼設(shè)計(jì),等無(wú)法滿足使用的時(shí)候才發(fā)現(xiàn)并不能達(dá)到需要的使用的性能,浪費(fèi)我們的項(xiàng)目時(shí)間。
性能指標(biāo):
以下性能數(shù)據(jù),是基于一個(gè)stream上下發(fā)10個(gè)異步媒體數(shù)據(jù)處理任務(wù)后,執(zhí)行一次aclrtSynchronizeStream接口。
對(duì)于非8K圖像,單個(gè)Device的基本場(chǎng)景性能指標(biāo)參考如下(1路對(duì)應(yīng)一個(gè)通道,一個(gè)通道對(duì)應(yīng)一個(gè)線程):
對(duì)于1080p的圖像,若存在Host->Device的圖片數(shù)據(jù)拷貝,由于拷貝帶寬限制,最大總幀率約為1000fps。
對(duì)于4K的圖像,若存在Host->Device的圖片數(shù)據(jù)拷貝,由于拷貝帶寬限制,最大總幀率約為250fps。

對(duì)于8K圖像,單個(gè)Device的典型場(chǎng)景性能指標(biāo)參考如下(1路對(duì)應(yīng)一個(gè)通道,一個(gè)通道對(duì)應(yīng)一個(gè)線程):

note:
VPC處理性能與處理過(guò)程中的圖像分辨率強(qiáng)相關(guān),以輸入圖像和輸出圖像中的最大分辨率作為基準(zhǔn)分辨率,基準(zhǔn)分辨率越大,處理耗時(shí)越久,性能越低。
調(diào)用VPC批處理接口(接口命名中包含Batch,例如acldvppVpcBatchCropAsync接口)時(shí),由于圖像處理單元DVPP(Digital Video Pre-Processing)內(nèi)部多個(gè)VPC硬件單元會(huì)并行處理圖片任務(wù),因此單路就可以達(dá)到最大總幀率。
圖片分辨率約束:
輸入圖片分辨率:支持如下分辨率的輸入圖片:
非8K:寬x高在10x6~4096x4096范圍內(nèi),包括4096。
8K:寬或高在4096~8192,不包括4096。
輸出圖片分辨率:10x6~4096x4096
輸出的寬高對(duì)齊:
這里我僅寫(xiě)出了我們下方代碼輸出的yuv420SP(NV12 8bit)的情況:
輸入圖片:
寬stride為寬16對(duì)齊后的值。
高stride為高2對(duì)齊后的值。
內(nèi)存大?。▎挝籅yte)≥ 寬stride * 高stride * 3/2
輸出圖片:
寬stride為寬16對(duì)齊后的值。
高stride為高2對(duì)齊后的值。
內(nèi)存大?。▎挝籅yte)≥ 寬stride * 高stride * 3/2
功能說(shuō)明:
以下僅寫(xiě)出了310可以使用的功能:
摳圖?:
從輸入圖片中摳出需要用的圖片區(qū)域,支持一圖多框和多圖多框。
縮放:
?針對(duì)不同分辨率的圖像,支持8K縮放、非8K縮放。
支持單圖裁剪縮放(支持非壓縮格式)、一圖多框裁剪縮放(支持非壓縮格式)。
其它縮放方式,如:原圖縮放、等比例縮放(縮放前后圖片的寬高比例相同)。
疊加?:
從輸入圖片中摳出來(lái)的圖,對(duì)摳出的圖進(jìn)行縮放后,放在用戶輸出圖片的指定區(qū)域,輸出圖片可以是空白圖片(由用戶申請(qǐng)的空輸出內(nèi)存產(chǎn)生的),也可以是已有圖片(由用戶申請(qǐng)輸出內(nèi)存后將已有圖片讀入輸出內(nèi)存),只有當(dāng)輸出圖片是已有圖片時(shí),才表示疊加。
拼接?:
從輸入圖片中摳多張圖片,對(duì)摳出的圖進(jìn)行縮放后,放到輸出圖片的指定區(qū)域。
格式轉(zhuǎn)換:
支持RGB格式、YUV格式之間的格式轉(zhuǎn)換。
圖像灰度化:
將彩色圖像轉(zhuǎn)化為灰度圖像。需注意,輸入為灰度圖像、輸出只能為灰度圖像。
昇騰310 AI處理器,實(shí)現(xiàn)圖像灰度化的操作是從YUV420SP格式的輸出圖像數(shù)據(jù)中只取Y分量的數(shù)據(jù)
示意圖:


接口說(shuō)明:
VPC的接口很多,我們這里只介紹一下我們用到的那個(gè):
二、代碼驗(yàn)證與學(xué)習(xí)
代碼思路:
1.讀取一個(gè)已知其寬高的yuv圖片,存入aclrtMalloc存入的內(nèi)存中
2.設(shè)置好dvpp的input和output通道的相關(guān)內(nèi)容。
3.調(diào)用vpc相關(guān)接口,輸出圖像。
4.保存圖像,查看結(jié)果,并按順序依次銷毀所有創(chuàng)建的device等。
這里其實(shí)就已經(jīng)清除的搞清楚我們需要做的事情啦,如下為代碼實(shí)現(xiàn):
runResize.cpp : 主函數(shù)。
dvpp_resize.cpp :主要為resize相關(guān)內(nèi)容函數(shù)
dvpp_resize.h :頭文件,存放相關(guān)結(jié)構(gòu)體
代碼就是如上啦,我們進(jìn)行代碼編譯咯!

運(yùn)行結(jié)果如下:

看樣子我們已經(jīng)成功的縮小了這個(gè)圖片,我選擇的是2048 x2048的圖片??s小后的大小為640x640的圖,放在了outYuv路徑下

我們來(lái)看看結(jié)果吧!這里我使用到的工具是yuvplayer,我們先看看原圖。
這里點(diǎn)擊size->custom我們選擇設(shè)置自己的圖像大小為2048 x 2048


然后設(shè)置圖片格式為NV12。

2048x2048的圖片實(shí)在是太大了,我的小小滴筆記本完全裝不下,這里我只截圖一部分。

看看我們縮小后的圖片!按照上面的設(shè)置方法,只是寬高設(shè)置為640和640

縮放成功??!和原圖一模一樣。大家可以再測(cè)試一下兩種分辨率之間來(lái)回縮放的時(shí)間,會(huì)發(fā)現(xiàn)放大是會(huì)耗時(shí)更多一點(diǎn)的。
好啦!到這里我們就實(shí)現(xiàn)了圖像縮放,把圖片縮放到了我們需要的大小,下一步就是把我們進(jìn)行decode和resize處理好的圖像進(jìn)行推理,獲得推理結(jié)果。
ps:該文僅是為了記錄CANN訓(xùn)練營(yíng)的學(xué)習(xí)過(guò)程所用,不參與任何商業(yè)用途,有任何代碼問(wèn)題可以和我一起討論修改