本文分享自華為雲社群《如何基於香橙派AIpro對影片/影像資料進行預處理》,作者: 昇騰CANN。
受網路結構和訓練方式等因素的影響,絕大多數神經網路模型對輸入資料都有格式上的限制。在計算機視覺領域,這個限制大多體現在影像的尺寸、色域、歸一化引數等。如果源圖或影片的尺寸、格式等與網路模型的要求不一致時,我們需要對其進行資料預處理。
昇騰AI硬體內建專門用於影像預處理的硬體單元,開發者透過其上層軟體棧CANN能夠更加便捷地發揮出硬體強大的媒體處理硬加速能力。香橙派AIpro開發板是香橙派聯合昇騰打造的高效能AI開發板,開發者可以基於此,對不滿足神經網路模型輸入要求的資料進行預處理,從而更好地完成AI推理計算。
01 昇騰CANN資料預處理方式簡介
昇騰CANN提供了兩種專門用於資料預處理的方式:AIPP和DVPP。
AIPP(Artificial Intelligence Pre-Processing)在AI Core上完成資料預處理,主要功能包括改變影像尺寸(摳圖、填充等)、色域轉換(轉換影像格式)、減均值/乘係數(改變影像畫素)等。AIPP區分為靜態AIPP和動態AIPP,您只能選擇其中一種方式,不支援兩種方式同時配置。- 靜態AIPP:模型轉換時設定AIPP模式為靜態,同時設定AIPP引數,模型生成後,AIPP引數值被儲存在離線模型(*.om)中,每次模型推理過程採用固定的AIPP預處理引數,無法修改。
- 動態AIPP:模型轉換時僅設定AIPP模式為動態,每次模型推理前,根據需求,在執行模型前設定動態AIPP引數值,然後在模型執行時可使用不同的AIPP引數。
總結一下,雖然都是資料預處理,但AIPP與DVPP的功能範圍不同(比如DVPP可以做影像編解碼、影片編解碼,AIPP可以做歸一化配置),處理資料的計算單元也不同,AIPP用的AI Core計算加速單元,DVPP就是用的專門的影像處理單元。
AIPP、DVPP可以分開獨立使用,也可以組合使用。組合使用場景下,一般先使用DVPP對圖片/影片進行解碼、摳圖、縮放等基本處理,再使用AIPP進行色域轉換、歸一化等處理。
02 如何使用AIPP功能
下文以此為例:測試圖片解析度為250*250、圖片格式為YUV420SP,模型對圖片的要求為解析度224*224、圖片格式為RGB,因此需要透過AIPP實現摳圖、圖片格式轉換2個功能。關於各種格式轉換,其色域轉換系數都有模板,可從ATC工具使用指南中獲取,請參見“昇騰文件中心”。
1、靜態AIPP
(1)構造AIPP配置檔案*.cfg。
- 摳圖,有效資料區域從左上角(0, 0)畫素開始,摳圖寬*高為224*224。
- 圖片格式轉換,輸入圖片格式為YUV420SP_U8,輸出圖片格式透過色域轉換系數控制。
aipp_op { aipp_mode : static # AIPP配置模式 input_format : YUV420SP_U8 # 輸入給AIPP的原始圖片格式 src_image_size_w : 250 # 輸入給AIPP的原始圖片寬高 src_image_size_h : 250 crop: true # 摳圖開關,用於改變圖片尺寸 load_start_pos_h: 0 # 摳圖起始位置水平、垂直方向座標 load_start_pos_w: 0 crop_size_w: 224 # 摳圖寬、高 crop_size_h: 224 csc_switch : true # 色域轉換開關 matrix_r0c0 : 256 # 色域轉換系數 matrix_r0c1 : 0 matrix_r0c2 : 359 matrix_r1c0 : 256 matrix_r1c1 : -88 matrix_r1c2 : -183 matrix_r2c0 : 256 matrix_r2c1 : 454 matrix_r2c2 : 0 input_bias_0 : 0 input_bias_1 : 128 input_bias_2 : 128 }
(2)使能靜態AIPP引數
使用ATC工具轉換模型時,可將AIPP配置檔案透過insert_op_conf引數傳入,將其配置引數儲存在模型檔案中。
atc --framework=3 --soc_version=${soc_version} --model= $HOME/module/resnet50_tensorflow.pb --insert_op_conf=$HOME/module/insert_op.cfg --output=$HOME/module/out/tf_resnet50
引數解釋如下:
- --framework:原始網路模型框架型別,3表示TensorFlow框架。
- --soc_version:指定模型轉換時昇騰AI處理器的版本,可執行npu-smi info命令進行查詢,在查詢到的“Name”前增加Ascend資訊,例如“Name”對應取值為xxxyy。
- --model:原始網路模型檔案路徑,含檔名。
- --insert_op_conf:AIPP預處理配置檔案路徑,含檔名。
- --output:轉換後的*.om模型檔案路徑,含檔名,轉換成功後,模型檔名自動以.om字尾結尾。
(3)呼叫AscendCL介面載入模型,執行推理,具體可參見如何基於香橙派AIpro開發AI推理應用。
2、動態AIPP
(1)構造AIPP配置檔案*.cfg。
aipp_op { aipp_mode: dynamic max_src_image_size: 752640 # 輸入影像最大記憶體大小,需根據實際情況調整 }
(2)使能動態AIPP。
使用ATC工具轉換模型時,可將AIPP配置檔案透過insert_op_conf引數傳入,將其配置引數儲存在模型檔案中。
atc --framework=3 --soc_version=${soc_version} --model= $HOME/module/resnet50_tensorflow.pb --insert_op_conf=$HOME/module/insert_op.cfg --output=$HOME/module/out/tf_resnet50
引數解釋如下:
- --framework:原始網路模型框架型別,3表示TensorFlow框架。
- --soc_version:指定模型轉換時昇騰AI處理器的版本。
- --model:原始網路模型檔案路徑,含檔名。
- --insert_op_conf:AIPP預處理配置檔案路徑,含檔名。
- --output:轉換後的*.om模型檔案路徑,含檔名,轉換成功後,模型檔名自動以.om字尾結尾。
(3)呼叫AscendCL介面載入模型,設定AIPP引數後,再執行推理,具體可參見如何基於香橙派AIpro開發AI推理應用。
呼叫AscendCL介面設定AIPP引數的程式碼示例如下:
aclmdlAIPP *aippDynamicSet = aclmdlCreateAIPP(batchNumber); aclmdlSetAIPPSrcImageSize(aippDynamicSet, 250, 250); aclmdlSetAIPPInputFormat(aippDynamicSet, ACL_YUV420SP_U8); aclmdlSetAIPPCscParams(aippDynamicSet, 1, 256, 0, 359, 256, -88, -183, 256, 454, 0, 0, 0, 0, 0, 128, 128); aclmdlSetAIPPCropParams(aippDynamicSet, 1, 2, 2, 224, 224, 0); aclmdlSetInputAIPP(modelId, input, index, aippDynamicSet); aclmdlDestroyAIPP(aippDynamicSet);
03 如何使用DVPP功能
昇騰AI處理器內建影像處理單元DVPP,提供了強大的媒體處理硬加速能力。同時,異構計算架構CANN提供了使用影像處理硬體算力的入口:AscendCL介面,開發者可透過介面來進行影像處理,以便利用昇騰AI處理器的算力。
DVPP內的功能模組如下表所示。
功能模組 |
描述 |
VPC(Vision Preprocessing Core) |
處理YUV、RGB等格式的圖片,包括縮放、摳圖、色域轉換、直方圖統計等。 |
JPEGD(JPEG Decoder) |
JPEG壓縮格式-->YUV格式的圖片解碼。 |
JPEGE(JPEG Encoder) |
YUV格式-->JPEG壓縮格式的圖片編碼。 |
VDEC(Video Decoder) |
H264/H265格式-->YUV/RGB格式的影片碼流解碼。 |
VENC(Video Encoder) |
YUV420SP格式-->H264/H265格式的影片碼流編碼。 |
PNGD(PNG decoder) |
PNG格式-->RGB格式的圖片解碼。 |
此處就以JPEGD圖片解碼+VPC圖片縮放為例來說明如何使用DVPP功能。這裡先透過一張圖總覽介面呼叫流程,包括資源初始化&去初始化、通道建立與銷燬、解碼、縮放、等待任務完成、釋放記憶體資源等。
總覽介面呼叫流程後,接下來我們以開發者更熟悉的方式“程式碼”來展示JPEGD圖片解碼+VPC圖片縮放功能的關鍵程式碼邏輯。
// 建立通道 acldvppChannelDesc dvppChannelDesc = acldvppCreateChannelDesc(); acldvppCreateChannel(dvppChannelDesc); // 在JPEGD圖片解碼前,準備其輸入、輸出 // …… // 建立解碼輸出圖片描述資訊,設定輸出圖片的寬、高、圖片格式、記憶體地址等 acldvppPicDesc decodeOutputDesc = acldvppCreatePicDesc(); acldvppSetPicDescData(decodeOutputDesc, decodeOutputBuffer)); acldvppSetPicDescWidth(decodeOutputDesc, decodeOutputWidth); acldvppSetPicDescHeight(decodeOutputDesc, decodeOutputHeight); // 此處省略其它set介面…… // 執行JPEGD圖片解碼 acldvppJpegDecodeAsync(dvppChannelDesc, decodeInputBuffer, decodeInputBufferSize, decodeOutputDesc, stream); // 5. 在VPC圖片縮放前,準備其輸入、輸出 // 建立縮放輸入圖片的描述資訊,並設定各屬性值,解碼的輸出作為縮放的輸入 acldvppPicDesc resizeInputDesc = acldvppCreatePicDesc(); acldvppSetPicDescData(resizeInputDesc, decodeOutputBuffer); acldvppSetPicDescWidth(resizeInputDesc, resizeInputWidth); acldvppSetPicDescHeight(resizeInputDesc, resizeInputHeight); // 此處省略其它set介面…… // 建立縮放輸出圖片的描述資訊,並設定各屬性值 acldvppPicDesc resizeOutputDesc = acldvppCreatePicDesc(); acldvppSetPicDescData(resizeOutputDesc, resizeOutputBuffer); acldvppSetPicDescWidth(resizeOutputDesc, resizeOutputWidth); acldvppSetPicDescHeight(resizeOutputDesc, resizeOutputHeight); // 此處省略其它set介面…… // 6. 執行VPC圖片縮放 acldvppVpcResizeAsync(dvppChannelDesc, resizeInputDesc, resizeOutputDesc, resizeConfig, stream); // 7. JPEGD圖片解碼、VPC圖片縮放都是非同步任務,需呼叫以下介面阻塞程式執行,直到指定Stream中的所有任務都完成 aclrtSynchronizeStream(stream);
04 更多學習資源
更多學習資源,歡迎登入昇騰社群查閱:
[1]昇騰文件中心:https://www.hiascend.com/zh/document
[2]香橙派AIpro開源樣例程式碼:https://gitee.com/ascend/EdgeAndRobotics
[3]香橙派AIpro學習資源一站式導航:https://www.hiascend.com/forum/thread-0285140173361311056-1-1.html
點選關注,第一時間瞭解華為雲新鮮技術~