AIPP部署
======

#### 基本概念

AIPP部署是指动态AIPP推理时开发者按需配置动态AIPP参数，从而达到使能AIPP功能。

#### 业务流程

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f6/v3/Nyf4Sg96Qfe2oU__mqfWXg/zh-cn_image_0000002625109035.png?HW-CC-KV=V1&HW-CC-Date=20260612T073656Z&HW-CC-Expire=86400&HW-CC-Sign=3BB57A04F7D136495DF237CA35E35C9BC15EDCAE65D73C4B0854F5A8F2E1ADFD)

#### 接口说明

以下接口为AIPP参数设置接口，如要使用更丰富的设置和查询接口，请参见[API参考](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit)。

**表1** CANN Kit模型推理AIPP设置相关接口功能介绍

| 接口名 | 描述 |
| :-- | :-- |
| HiAI\_AippParam\* HMS\_HiAIAippParam\_Create(uint32\_t batchNum); | 动态AIPP配置实例创建。 |
| void HMS\_HiAIAippParam\_Destroy(HiAI\_AippParam\*\* aippParam); | 动态AIPP配置实例销毁。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetInputIndex(HiAI\_AippParam\* aippParam, uint32\_t inputIndex); | 设置动态AIPP配置作用于输入上的索引。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetInputAippIndex(HiAI\_AippParam\* aippParam, uint32\_t inputAippIndex); | 设置动态AIPP配置作用于该输入的多个输出分支上的索引。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetInputFormat(HiAI\_AippParam\* aippParam, HiAI\_ImageFormat inputFormat); | 设置输入图片的格式。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetInputShape(HiAI\_AippParam\* aippParam, uint32\_t srcImageW, uint32\_t srcImageH); | 设置输入图片的原始宽高。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetCscConfig(HiAI\_AippParam\* aippParam, HiAI\_ImageFormat inputFormat, HiAI\_ImageFormat outputFormat, HiAI\_ImageColorSpace space); | 设置图片色域转换参数。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetChannelSwapConfig(HiAI\_AippParam\* aippParam, bool rbuvSwapSwitch, bool axSwapSwitch); | 设置图片通道交换参数。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetCropConfig(HiAI\_AippParam\* aippParam, uint32\_t batchIndex, uint32\_t startPosW, uint32\_t startPosH, uint32\_t croppedW, uint32\_t croppedH); | 设置图片裁剪参数。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetResizeConfig(HiAI\_AippParam\* aippParam, uint32\_t batchIndex, uint32\_t resizedW, uint32\_t resizedH); | 设置图片缩放大小参数。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetPadConfig(HiAI\_AippParam\* aippParam, uint32\_t batchIndex, uint32\_t leftPadSize, uint32\_t rightPadSize, uint32\_t topPadSize, uint32\_t bottomPadSize); | 设置图片左右上下填充的像素数。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetChannelPadding(HiAI\_AippParam\* aippParam, uint32\_t batchIndex, uint32\_t paddingValues\[\], uint32\_t channelCount); | 设置通道填充值。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetRotationAngle(HiAI\_AippParam\* aippParam, uint32\_t batchIndex, float rotationAngle); | 设置图片旋转参数。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetDtcMeanPixel(HiAI\_AippParam\* aippParam, uint32\_t batchIndex, uint32\_t meanPixel\[\], uint32\_t channelCount); | 设置图片数据类型转换的通道像素平均值。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetDtcMinPixel(HiAI\_AippParam\* aippParam, uint32\_t batchIndex, float minPixel\[\], uint32\_t channelCount); | 设置图片数据类型转换的通道像素最小值。 |
| OH\_NN\_ReturnCode HMS\_HiAIAippParam\_SetDtcVarReciPixel(HiAI\_AippParam\* aippParam, uint32\_t batchIndex, float varReciPixel\[\], uint32\_t channelCount); | 设置图片数据类型转换的通道像素方差。 |
| OH\_NN\_ReturnCode HMS\_HiAITensor\_SetAippParams(NN\_Tensor\* tensor, HiAI\_AippParam\* aippParams\[\], size\_t aippNum); | 给输入Tensor设置AIPP参数。 |

#### 开发步骤

1.  调用[HMS\_HiAIAippParam\_Create](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_create)创建动态AIPP配置实例。
    
2.  设置与计算图关联的配置。
    
    *   调用[HMS\_HiAIAippParam\_SetInputIndex](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setinputindex)设置此动态AIPP配置所在输入的索引。
    *   调用[HMS\_HiAIAippParam\_SetInputAippIndex](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setinputaippindex)设置此动态AIPP配置所在某个输入的输出分支索引。
3.  设置动态AIPP输入图片相关配置。
    
    *   调用[HMS\_HiAIAippParam\_SetInputFormat](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setinputformat)设置输入图片的格式。
    *   调用[HMS\_HiAIAippParam\_SetInputShape](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setinputshape)设置输入图片原始宽高。
4.  开发者按需设置以下动态AIPP功能参数。
    
    *   调用[HMS\_HiAIAippParam\_SetChannelSwapConfig](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setchannelswapconfig)设置通道交换参数。
    *   调用[HMS\_HiAIAippParam\_SetCscConfig](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setcscconfig)设置图片色域转换参数。
    *   调用[HMS\_HiAIAippParam\_SetCropConfig](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setcropconfig)设置图片裁剪参数。
    *   调用[HMS\_HiAIAippParam\_SetResizeConfig](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setresizeconfig)设置图片缩放大小参数。
    *   调用[HMS\_HiAIAippParam\_SetPadConfig](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setpadconfig)设置图片填充大小参数。
    *   调用[HMS\_HiAIAippParam\_SetChannelPadding](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setchannelpadding)设置各通道上的填充值参数。
    *   调用[HMS\_HiAIAippParam\_SetRotationAngle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setrotationangle)设置旋转角度。
    *   调用[HMS\_HiAIAippParam\_SetDtcMeanPixel](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setdtcmeanpixel)设置数据类型转换通道像素平均值。
    *   调用[HMS\_HiAIAippParam\_SetDtcMinPixel](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setdtcminpixel)设置数据类型转换通道像素最小值。
    *   调用[HMS\_HiAIAippParam\_SetDtcVarReciPixel](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_setdtcvarrecipixel)设置数据类型转换通道像素方差。
5.  将AIPP配置设置到[NN\_Tensor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-neuralnetworkruntime-nn-tensor)。
    
    通过构造输入输出Tensor后，调用[HMS\_HiAITensor\_SetAippParams](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaitensor_setaippparams)给输入Tensor设置AIPP参数。
    
6.  执行模型推理。
    
7.  调用[HMS\_HiAIAippParam\_Destroy](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/cannkit#hms_hiaiaippparam_destroy)销毁动态AIPP配置实例。
    

#### 示例说明

假定当前有一个模型，训练时采用的训练集为RGB888的图片，使能了动态AIPP之后，可以接收YUYV类型的图片作为模型推理的输入。当用于模型推理的图片尺寸与训练集不一致时，还可以使用AIPP的裁剪、缩放和填充功能，改变输入图片尺寸。以下示例代码基于NDK接口，实现AIPP的裁剪、缩放和填充等功能，将一张YUYV尺寸为480x480的图片预处理为224x224的输入。

#include "neural\_network\_runtime/neural\_network\_core.h"
#include "CANNKit/hiai\_aipp\_param.h"
#include "CANNKit/hiai\_tensor.h"
#include <vector>

constexpr uint32\_t BATCH\_NUM = 1;
// 创建一个batch数为1的动态aipp配置实例
HiAI\_AippParam\* aippPara = HMS\_HiAIAippParam\_Create(BATCH\_NUM);
// 在多个输入情况下，设置索引以确定该AippParam对象作用于第几个输入
uint32\_t inputIndex = 0;
OH\_NN\_ReturnCode ret = HMS\_HiAIAippParam\_SetInputIndex(aippPara, inputIndex);
// 在data有多个输出分支时，设置AippParam对象作用域该输入的第几个输出分支
uint32\_t validInputAippIndex = 0;
HMS\_HiAIAippParam\_SetInputAippIndex(aippPara, validInputAippIndex);
// 设置AippParam对象的输入图像格式
HMS\_HiAIAippParam\_SetInputFormat(aippPara, HIAI\_YUV420SP\_U8);
// 设置AippParam对象的输入图像宽高
HMS\_HiAIAippParam\_SetInputShape(aippPara, 224, 224);
// 设置AippParam对象的CSC色域转换参数
HMS\_HiAIAippParam\_SetCscConfig(aippPara, HIAI\_YUV420SP\_U8, HIAI\_RGB888\_U8, HIAI\_JPEG);
// 设置AippParam对象RB/UV通道交换
HMS\_HiAIAippParam\_SetChannelSwapConfig(aippPara, true, false);
// 设置AippParam对象第0个索引batch的crop参数
HMS\_HiAIAippParam\_SetCropConfig(aippPara, 0, 0, 0, 100, 100);
// 设置AippParam对象第0个索引batch的resize参数
HMS\_HiAIAippParam\_SetResizeConfig(aippPara, 0, 110, 110);
// 设置AippParam对象第0个索引batch的通道padding填充值
HMS\_HiAIAippParam\_SetPadConfig(aippPara, 0, 1, 1, 1, 1);
// 设置AippParam对象第0个索引batch的旋转角度
HMS\_HiAIAippParam\_SetRotationAngle(aippPara, 0, 90.0);
// 设置AippParam对象第0个batch的数据类型转换通道像素平均值
constexpr unsigned int chnNum = 4;
unsigned int pixelMeanPara\[chnNum\] = {1, 2, 3, 4};
HMS\_HiAIAippParam\_SetDtcMeanPixel(aippPara, 0, pixelMeanPara, chnNum);

// 准备输入Tensor
size\_t inputCount = 0;
ret = OH\_NNExecutor\_GetInputCount(executor, &inputCount); // 创建executor可参考CANN Kit Codelab
std::vector<NN\_Tensor \*> inputTensors;
for (size\_t i = 0; i < inputCount; ++i) {
    // 创建executor可参考CANN Kit Codelab
    NN\_TensorDesc\* desc = OH\_NNExecutor\_CreateInputTensorDesc(executor, i);
    NN\_Tensor\* tensor = OH\_NNTensor\_Create(deviceID, desc); // 获取deviceID可参考CANN Kit Codelab
    inputTensors.push\_back(tensor);
}
// 准备aipp输入Tensor
HiAI\_AippParam\* aippParas\[1\] = {aippPara};
NN\_Tensor\* tensor = nullptr;
ret = HMS\_HiAITensor\_SetAippParams(tensor, aippParas, 1);
if (ret != OH\_NN\_SUCCESS ) {
    return;
}
inputTensors.push\_back(tensor);

// 准备输出Tensor
size\_t outputCount = 0;
ret = OH\_NNExecutor\_GetOutputCount(executor, &outputCount); // 创建executor可参考CANN Kit Codelab
std::vector<NN\_Tensor \*> outputTensors;
for (size\_t i = 0; i < outputCount; i++) {
    NN\_TensorDesc\* desc = OH\_NNExecutor\_CreateOutputTensorDesc(executor, i); // 创建executor可参考CANN Kit Codelab
    NN\_Tensor\* tensor = OH\_NNTensor\_Create(deviceID, desc); // 获取deviceID可参考CANN Kit Codelab
    outputTensors.push\_back(tensor);
}
// 执行推理
ret = OH\_NNExecutor\_RunSync(executor\_, inputTensors.data(), 1, outputTensors.data(), 1);
if (ret != OH\_NN\_SUCCESS ) {
    return;
}
if (aippPara != nullptr) {
    HMS\_HiAIAippParam\_Destroy(&aippPara);
}