跳到主要内容

模型执行

模型执行

基本原理

开发应用时,如果涉及整网模型推理,则应用程序中必须包含模型执行的代码逻辑,关于模型执行的接口调用流程。请先参见pyACL接口调用流程了解整体流程,再查看本节中的流程说明。

本节描述的是整网模型执行的接口调用流程,对于算子模型加载与执行的详细说明请参见单算子调用

  • 在模型加载之后,模型执行之前,需要准备输入、输出数据结构,将输入数据传输到模型输入数据结构的对应内存中。

  • 模型执行结束后,若无需使用输入数据、aclmdlDesc类型、aclmdlDataset类型、aclDataBuffer类型等相关资源,需及时释放内存、销毁对应的数据类型,防止内存异常。

    模型可能存在多个输入、多个输出,每个输入/输出的内存地址、内存大小用aclDataBuffer类型的数据来描述,针对每个输入/输出,需调用acl.destroy_data_buffer接口销毁相应的aclDataBuffer类型,并调用acl.rt.free接口释放内存中的数据。

接口调用流程

图1 基本的模型推理流程

关键接口的说明如下:

  1. 调用acl.mdl.create_desc接口创建描述模型基本信息的数据类型。

  2. 调用acl.mdl.get_desc接口根据模型加载中返回的模型ID获取模型基本信息

  3. 准备模型执行的输入、输出数据结构,具体流程请参见准备模型执行的输入/输出数据结构

    如果模型的输入涉及动态Batch动态分辨率动态AIPP动态维度(ND格式)等特性,请参见模型动态推理模型动态AIPP推理

  4. 执行模型推理

    对于固定的多Batch场景,需要满足Batch数后,才能将输入数据发送给模型进行推理。不满足Batch数时,用户需根据自己的实际场景处理。

    当前系统支持模型的同步推理和异步推理:

  5. 获取模型推理的结果,用于后续处理。

    对于同步推理,直接获取模型推理的输出数据即可。

    对于异步推理,在实现Callback功能时,在回调函数内获取模型推理的结果,供后续使用。

  6. 释放内存

    调用acl.rt.free接口释放Device上的内存。

  7. 释放相关数据类型的数据

    在模型推理结束后,需及时依次调用acl.destroy_data_buffer接口和acl.mdl.destroy_dataset接口释放描述模型输入的数据。如果存在多个输入、输出,需调用多次acl.destroy_data_buffer接口。

准备模型执行的输入/输出数据结构

pyACL提供了以下数据类型来描述模型、模型输入、模型输出以及存放数据的内存,在模型执行前,需要构造好这些数据类型,作为模型执行的输入:

  • 使用aclmdlDesc类型的数据描述模型基本信息(例如输入/输出的个数、名称、数据类型、Format、维度信息等)。

    模型加载成功后,用户可根据模型的ID,调用acl.mdl.get_desc接口获取该模型的描述信息,进而从模型的描述信息中获取模型输入/输出的个数、内存大小、维度信息、Format、数据类型等信息,可参见aclmdlDesc类型下的操作接口。

  • 使用aclmdlDataset类型的数据描述模型的输入/输出数据,模型可能存在多个输入、多个输出。

    调用aclmdlDataset类型下的操作接口添加aclDataBuffer类型的数据、获取aclDataBuffer的个数等。

  • 每个输入/输出的内存地址、内存大小用aclDataBuffer类型的数据来描述。

    调用aclDataBuffer类型下的操作接口获取内存地址、内存大小等。

图2 aclmdlDataset类型与aclDataBuffer类型的关系

了解相关的数据类型后,可以使用这些数据类型的操作接口准备模型的输入、输出数据结构,如下图所示。

图3 模型执行的输入/输出数据结构的准备流程

关键说明如下:

示例代码(准备模型的输入和输出数据结构)

您可以从样例介绍中获取完整样例代码。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

## 初始化变量。
ACL_MEM_MALLOC_HUGE_FIRST = 0

## 1.根据模型的ID,获取该模型的描述信息。
## self.model_desc为aclmdlDesc类型。
self.model_desc = acl.mdl.create_desc()
ret = acl.mdl.get_desc(self.model_desc, self.model_id)

## 2.准备模型推理的输入数据集。
## 创建aclmdlDataset类型的数据,描述模型推理的输入。
self.load_input_dataset = acl.mdl.create_dataset()
## 获取模型输入的数量。
input_size = acl.mdl.get_num_inputs(self.model_desc)
self.input_data = []
## 循环为每个输入申请内存,并将每个输入添加到aclmdlDataset类型的数据中。
for i in range(input_size):
buffer_size = acl.mdl.get_input_size_by_index(self.model_desc, i)
# 申请输入内存。
buffer, ret = acl.rt.malloc(buffer_size, ACL_MEM_MALLOC_HUGE_FIRST)
data = acl.create_data_buffer(buffer, buffer_size)
_, ret = acl.mdl.add_dataset_buffer(self.load_input_dataset, data)
self.input_data.append({"buffer": buffer, "size": buffer_size})

## 3.准备模型推理的输出数据集。
## 创建aclmdlDataset类型的数据,描述模型推理的输出。
self.load_output_dataset = acl.mdl.create_dataset()
## 获取模型输出的数量。
output_size = acl.mdl.get_num_outputs(self.model_desc)
self.output_data = []
## 循环为每个输出申请内存,并将每个输出添加到aclmdlDataset类型的数据中。
for i in range(output_size):
buffer_size = acl.mdl.get_output_size_by_index(self.model_desc, i)
# 申请输出内存。
buffer, ret = acl.rt.malloc(buffer_size, ACL_MEM_MALLOC_HUGE_FIRST)
data = acl.create_data_buffer(buffer, buffer_size)
_, ret = acl.mdl.add_dataset_buffer(self.load_output_dataset, data)
self.output_data.append({"buffer": buffer, "size": buffer_size})

## ......

示例代码(执行模型)

您可以从样例介绍中获取完整样例代码。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

ACL_MEMCPY_HOST_TO_DEVICE = 1
ACL_MEMCPY_DEVICE_TO_HOST = 2
NPY_BYTE = 1
images_list = ["./data/dog1_1024_683.jpg", "./data/dog2_1024_683.jpg"]

for image in images_list:
# 1.自定义函数transfer_pic,使用Python库读取图片文件,并对图片进行缩放、剪裁等操作。
# transfer_pic函数的实现请参考样例中源代码。
img = transfer_pic(image)

# 2.准备模型推理的输入数据,运行模式默认为运行模式为ACL_HOST,当前实例代码中模型只有一个输入。

bytes_data = img.tobytes()
np_ptr = acl.util.bytes_to_ptr(bytes_data)
# 将图片数据从Host传输到Device。
ret = acl.rt.memcpy(self.input_data[0]["buffer"], self.input_data[0]["size"], np_ptr,
self.input_data[0]["size"], ACL_MEMCPY_HOST_TO_DEVICE)

# 3.执行模型推理。
# self.model_id表示模型ID,在模型加载成功后,会返回标识模型的ID。
ret = acl.mdl.execute(self.model_id, self.load_input_dataset, self.load_output_dataset)

## ......

示例代码(处理推理结果:直接处理内存中的数据)

您可以从样例介绍中获取完整样例代码。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

以图片分类网络为例,模型执行结束后,需处理每一张图片的模型推理结果,直接输出top5置信度的类别编号。

## 处理模型推理的输出数据,输出top5置信度的类别编号。
inference_result = []
for i, item in enumerate(self.output_data):
buffer_host, ret = acl.rt.malloc_host(self.output_data[i]["size"])
# 将推理输出数据从Device传输到Host。
ret = acl.rt.memcpy(buffer_host, self.output_data[i]["size"], self.output_data[i]["buffer"],
self.output_data[i]["size"], ACL_MEMCPY_DEVICE_TO_HOST)

bytes_out = acl.util.ptr_to_bytes(buffer_host, self.output_data[i]["size"])
data = np.frombuffer(bytes_out, dtype=np.byte)

inference_result.append(data)
tuple_st = struct.unpack("1000f", bytearray(inference_result[0]))
vals = np.array(tuple_st).flatten()
top_k = vals.argsort()[-1:-6:-1]
print("======== top5 inference results: =============")
for j in top_k:
print("[%d]: %f" % (j, vals[j]))

## ......

示例代码(释放模型的输入、输出资源)

您可以从样例介绍中获取完整样例代码。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br><br># 释放模型推理的输入、输出资源。<br># 释放输入资源,包括数据结构和内存。<br>while self.input_data:<br> item = self.input_data.pop()<br> ret = acl.rt.free(item["buffer"])<br>input_number = acl.mdl.get_dataset_num_buffers(self.load_input_dataset)<br>for i in range(input_number):<br> data_buf = acl.mdl.get_dataset_buffer(self.load_input_dataset, i)<br> if data_buf:<br> ret = acl.destroy_data_buffer(data_buf)<br>ret = acl.mdl.destroy_dataset(self.load_input_dataset)<br># 释放输出资源,包括数据结构和内存。<br>while self.output_data:<br> item = self.output_data.pop()<br> ret = acl.rt.free(item["buffer"])<br>output_number = acl.mdl.get_dataset_num_buffers(self.load_output_dataset)<br>for i in range(output_number):<br> data_buf = acl.mdl.get_dataset_buffer(self.load_output_dataset, i)<br> if data_buf:<br> ret = acl.destroy_data_buffer(data_buf)<br>ret = acl.mdl.destroy_dataset(self.load_output_dataset)<br>

父主题: 模型推理基本场景

模型卸载

关于模型卸载的接口调用流程,请参见pyACL接口调用流程

基本原理

在模型推理结束后,还需要通过acl.mdl.unload接口卸载模型,并销毁aclmdlDesc类型的模型描述信息。

示例代码

## 卸载模型。
ret = acl.mdl.unload(self.model_id)

## 释放模型描述信息。
if self.model_desc:
ret = acl.mdl.destroy_desc(self.model_desc)
self.model_desc = None

父主题: 模型推理基本场景

媒体数据处理基础知识

本章主要介绍图像/视频数据处理的具体功能、接口调用流程以及示例代码。

DVPP图像/视频数据处理的典型使用场景

如果源图或视频的分辨率、格式等与模型的要求不一致时,我们可以将源图或视频处理成符合模型的要求。如下为典型场景的举例

  • 视频解码、缩放

    使用YOLOv3模型实现目标检测的场景下,用户提供的输入视频为H264/H265编码格式、分辨率为1920*1080,但YOLOv3模型要求的输入图片格式为RGB/YUV、分辨率为416*416,两者不一致,此时可对视频执行以下一系列处理。

    图1 视频解码、缩放使用场景图

  • 图片解码、缩放、格式转换

    使用ResNet-50模型实现图片分类的场景下,用户提供的输入图片为JPEG编码格式、分辨率为1280*720,但ResNet-50模型要求的输入图片格式为RGB、分辨率为224*224,两者不一致,此时可对图片执行以下一系列处理。

    图2 图片解码、缩放、格式转换使用场景图

  • 抠图、缩放、格式转换

    使用ResNet-50模型实现图片分类的场景下,用户提供的输入图片格式为YUV420SP、分辨率为1280*720,但ResNet-50模型要求的输入图片格式为RGB、分辨率为224*224,两者不一致,此时对图片执行以下一系列处理。

    图3 抠图、缩放、格式转换使用场景图

媒体数据处理功能开发流程

图4 开发流程

  1. 准备环境

    请参见应用开发环境准备

  2. 创建代码目录

    在开发应用前,您需要先创建目录,存放代码文件、脚本、测试图片数据、模型文件等。

  3. (可选)构建模型

    模型推理场景下,必须要有适配昇腾AI处理器的离线模型(*.om文件),请参见模型构建

    :::note 说明 如果应用中涉及模型推理,则需要构建模型。 :::

  4. 开发应用

    如果应用中涉及模型推理,请参见模型推理基本场景扩展更多特性编写相应的代码。

  5. 运行应用,请参见应用调试

父主题: 媒体数据处理

V1与V2版本的差别

本手册中媒体数据处理V1版本与媒体数据处理V2版本的接口都是描述处理媒体数据的接口,用于实现抠图、图片缩放、格式转换等功能,但两套接口不能混用

V2版本的功能比V1版本更多,参见如下:

  • JPEGE:V2版本接口支持高级的参数配置,如huffman表配置。
  • VENC:V2版本接口支持更加细化的码控参数配置和效果调优,如I/P帧QP、宏块码控等。
  • VDEC:V2版本接口支持更细化的内存控制,如设置输入码流缓存。

昇腾AI处理器对V2版本各功能的支持度,请参见功能支持度说明

父主题: 媒体数据处理

功能支持度说明

昇腾AI处理器对媒体数据处理V1版本各功能的支持度如下表所示。

昇腾AI处理器VPCJPEGDJPEGEPNGDVDECVENC
Atlas 200/500 A2推理产品

父主题: 媒体数据处理V1

VPC图像处理典型功能

VPC(Vision Preprocessing Core)负责图像处理功能,支持对图片做抠图、缩放、格式转换等操作。关于VPC功能的详细介绍请参见功能说明,关于VPC功能对输入、输出的约束要求,请参见约束说明

本节以抠图、缩放为例说明VPC图像处理时的接口调用流程,同时配合以下典型功能的示例代码辅助理解该接口调用流程:

接口调用流程(以抠图、缩放为例)

开发应用时,如果涉及抠图、缩放等图片处理,则应用程序中必须包含图片处理的代码逻辑,关于图片处理的接口调用流程,请先参见pyACL接口调用流程了解整体流程,再查看本节中的流程说明

图1 抠图缩放流程

关键接口的说明如下(以抠图、缩放处理为例):

  1. 调用acl.media.dvpp_create_channel_desc接口创建通道描述信息

  2. 调用acl.media.dvpp_create_channel接口创建图片数据处理的通道

  3. 调用acl.media.dvpp_create_roi_config接口、acl.media.dvpp_create_resize_config接口分别创建抠图区域位置的配置、缩放配置

  4. 实现抠图、缩放功能前,若需要申请Device上的内存存放输入或输出数据,需调用acl.media.dvpp_malloc申请内存。

  5. 执行抠图、缩放

    • 关于抠图:
      • 调用acl.media.dvpp_vpc_crop_async异步接口,按指定区域从输入图片中抠图,再将抠的图片存放到输出内存中,作为输出图片。

        输出图片区域与抠图区域“crop_area”不一致时会对图片再做一次缩放操作。

      • 当前系统还提供了acl.media.dvpp_vpc_crop_and_paste_async异步接口,支持按指定区域从输入图片中抠图,再将抠的图片贴到目标图片的指定位置,作为输出图片。

        • 抠图区域“crop_area”的宽高与贴图区域“paste_area”宽高不一致时会对图片再做一次缩放操作。
        • 如果用户需要将目标图片读入内存用于存放输出图片,将贴图区域叠加在目标图片上,则需要编写代码逻辑:在申请输出内存后,将目标图片读入输出内存
    • 关于缩放:
      • 调用acl.media.dvpp_vpc_resize_async异步接口,将输入图片缩放到输出图片大小
      • 缩放后输出图片内存根据YUV420SP格式计算,计算公式:对齐后的宽 * 对齐后的高 * 3 / 2
    • 对于异步接口,还需调用acl.rt.synchronize_stream接口阻塞程序运行,直到指定Stream中的所有任务都完成。
  6. 调用acl.media.dvpp_free接口释放输入、输出内存

  7. 调用acl.media.dvpp_destroy_roi_config接口、acl.media.dvpp_destroy_resize_config接口分别销毁抠图区域位置的配置、缩放配置

  8. 调用acl.media.dvpp_destroy_channel接口销毁图片数据处理的通道

    销毁图片数据处理的通道后,再调用acl.media.dvpp_destroy_channel_desc接口销毁通道描述信息。

图片缩放示例代码

您可以从获取样例中获取完整样例代码。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br>74<br>75<br>76<br>python<br>import acl<br># ......<br># 1.ACL初始化。<br>ret = acl.init()<br># 2.运行管理资源申请,包括Device、Context、Stream。<br>self.device_id = 0<br>ret = acl.rt.set_device(self.device_id)<br>self.context, ret = acl.rt.create_context(self.device_id)<br>self.stream, ret = acl.rt.create_stream()<br># 3.创建图片缩放配置数据,不支持指定缩放算法,默认缩放算法为“最近邻插值”。<br># self.resize_config是acldvppResizeConfig类型。<br>self.resize_config = acl.media.dvpp_create_resize_config()<br># 4.创建图片数据处理通道时的通道描述信息,self.dvpp_channel_desc是acldvppChannelDesc类型。<br>self.dvpp_channel_desc = acl.media.dvpp_create_channel_desc()<br># 5.创建图片数据处理的通道。<br>ret = acl.media.dvpp_create_channel(self.dvpp_channel_desc)<br># 6.申请缩放输入内存,内存大小根据计算公式得出; w和h是输入图片的实际尺寸。<br>width_stride = ((w + 15) // 16) * 16<br>height_stride = ((h + 1) // 2) * 2<br>buffer_size = (width_stride * height_stride * 3) // 2<br>dev_in, ret = acl.media.dvpp_malloc(buffer_size )<br>self.dev_buffer['input_0'] = dev<br># 7.申请缩放输出内存,内存大小根据计算公式得出; w和h是输入图片的缩放尺寸。<br>width_stride = ((w + 15) // 16) * 16<br>height_stride = ((h + 1) // 2) * 2<br>buffer_size = (width_stride * height_stride * 3) // 2<br>dev_out, ret = acl.media.dvpp_malloc(buffer_size )<br>self.dev_buffer['output_0'] = dev<br># 8.创建缩放输入图片的描述信息,并设置各属性值。<br># self.input_desc是acldvppPicDesc类型。<br>self.input_desc = acl.media.dvpp_create_pic_desc()<br>ret = acl.media.dvpp_set_pic_desc_data(self.input_desc, buffer)<br>ret = acl.media.dvpp_set_pic_desc_format(self.input_desc, YUV420)<br>ret = acl.media.dvpp_set_pic_desc_width(self.input_desc, width)<br>ret = acl.media.dvpp_set_pic_desc_height(self.input_desc, height)<br>ret = acl.media.dvpp_set_pic_desc_width_stride(self.input_desc, wstride)<br>ret = acl.media.dvpp_set_pic_desc_height_stride(self.input_desc, hstride)<br>ret = acl.media.dvpp_set_pic_desc_size(self.input_desc, size)<br># 9.创建缩放输出图片的描述信息,并设置各属性值。<br># 如果缩放的输出图片作为模型推理的输入,则输出图片的宽高要与模型要求的宽高保持一致。<br># self.output_desc是acldvppPicDesc类型。<br>self.output_desc= acl.media.dvpp_create_pic_desc()<br>ret = acl.media.dvpp_set_pic_desc_data(self.output_desc, buffer)<br>ret = acl.media.dvpp_set_pic_desc_format(self.output_desc, YUV420)<br>ret = acl.media.dvpp_set_pic_desc_width(self.output_desc, width)<br>ret = acl.media.dvpp_set_pic_desc_height(self.output_desc, height)<br>ret = acl.media.dvpp_set_pic_desc_width_stride(self.output_desc, wstride)<br>ret = acl.media.dvpp_set_pic_desc_height_stride(self.output_desc, hstride)<br>ret = acl.media.dvpp_set_pic_desc_size(self.output_desc, size)<br># 10.执行异步缩放,再调用acl.rt.synchronize_stream接口阻塞Host运行,直到指定Stream中的所有任务都完成。<br>ret = acl.media.dvpp_vpc_resize_async(self.dvpp_channel_desc, self.input_desc,<br> self.output_desc, self.resize_config,<br> self.stream)<br>ret = acl.rt.synchronize_stream(self.stream)<br># 11.缩放结束后,释放资源,包括缩放输入/输出图片的描述信息、缩放输入/输出内存。<br>ret = acl.media.dvpp_destroy_pic_desc(self.output_desc)<br>ret = acl.media.dvpp_destroy_pic_desc(self.input_desc)<br>ret = acl.media.dvpp_free(self.dev_buffer['input_0'] )<br>ret = acl.media.dvpp_free(self.dev_buffer['output_0'] )<br># 12.释放运行管理资源。<br>ret = acl.rt.destroy_stream(self.stream)<br>ret = acl.rt.destroy_context(self.context)<br>ret = acl.rt.reset_device(self.device_id)<br>ret = acl.finalize()<br># ......<br>

格式转换示例代码

格式转换支持以下两种实现方式:

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br>74<br>75<br>76<br>77<br>78<br>79<br>80<br>81<br>82<br>83<br>84<br>85<br>86<br>87<br>88<br>python<br>import acl<br># ......<br>ACL_MEMCPY_HOST_TO_DEVICE = 1<br>ACL_MEMCPY_DEVICE_TO_HOST = 2<br>PIXEL_FORMAT_YUV_400 = 0<br>PIXEL_FORMAT_YUV_SEMIPLANAR_420 = 1<br># 1.ACL初始化。<br>ret = acl.init()<br># 2.运行管理资源申请,包括Device、Context、Stream。<br>device_id = 0<br>ret = acl.rt.set_device(device_id)<br>context, ret = acl.rt.create_context(device_id)<br>stream, ret = acl.rt.create_stream()<br># 3.创建图片数据处理通道时的通道描述信息,dvpp_channel_desc是acldvppChannelDesc类型。<br>dvpp_channel_desc = acl.media.dvpp_create_channel_desc()<br># 4.创建图片数据处理的通道。<br>ret = acl.media.dvpp_create_channel(dvpp_channel_desc)<br># 5.申请输入内存。<br>input_width_stride = ((input_width + 15) // 16) * 16<br>input_height_stride = ((input_height + 1) // 2) * 2<br># input_width_stride、input_height_stride分别表示图片的对齐后宽、对齐后高,此处以YUV420SP格式的图片为例。<br>in_buffer_size = (input_width_stride * input_height_stride * 3) // 2<br>in_dev_buffer, ret = acl.media.dvpp_malloc(in_buffer_size)<br>np_yuv = np.fromfile(path, dtype=np.byte)<br>buffer_size = np_yuv.itemsize * np_yuv.size<br>bytes_data = np_yuv.tobytes()<br>np_yuv_ptr = acl.util.bytes_to_ptr(bytes_data)<br>ret = acl.rt.memcpy(in_dev_buffer, buffer_size, np_yuv_ptr,<br> buffer_size, ACL_MEMCPY_HOST_TO_DEVICE)<br># 6.申请色域转换输出内存。<br>output_width_stride = ((output_width + 15) // 16) * 16<br>output_height_stride = ((output_height + 1) // 2) * 2<br># output_width_stride、output_height_stride分别表示图片的对齐后宽、对齐后高,此处以YUV420SP格式的图片为例。<br>out_buffer_size = (output_width_stride * output_height_stride * 3) // 2<br>out_dev_buffer, ret = acl.media.dvpp_malloc(out_buffer_size)<br># 7.创建色域转换输入图片的描述信息,并设置各属性值。<br>input_desc = acl.media.dvpp_create_pic_desc()<br>ret = acl.media.dvpp_set_pic_desc_data(input_desc, in_dev_buffer)<br>ret = acl.media.dvpp_set_pic_desc_format(input_desc, PIXEL_FORMAT_YUV_SEMIPLANAR_420)<br>ret = acl.media.dvpp_set_pic_desc_width(input_desc, input_width)<br>ret = acl.media.dvpp_set_pic_desc_height(input_desc, input_height)<br>ret = acl.media.dvpp_set_pic_desc_width_stride(input_desc, input_width_stride)<br>ret = acl.media.dvpp_set_pic_desc_height_stride(input_desc, input_height_stride)<br>ret = acl.media.dvpp_set_pic_desc_size(input_desc, in_buffer_size)<br># 8.创建色域转换的输出图片的描述信息,并设置各属性值, 输出的宽和高要求和输入一致。<br># 如果色域转换的输出图片作为模型推理的输入,则输出图片的宽高要与模型要求的宽高保持一致。<br>output_desc = acl.media.dvpp_create_pic_desc()<br>ret = acl.media.dvpp_set_pic_desc_data(output_desc, out_dev_buffer)<br>ret = acl.media.dvpp_set_pic_desc_format(output_desc, PIXEL_FORMAT_YUV_400)<br>ret = acl.media.dvpp_set_pic_desc_width(output_desc, output_width)<br>ret = acl.media.dvpp_set_pic_desc_height(output_desc, output_height)<br>ret = acl.media.dvpp_set_pic_desc_width_stride(output_desc, output_width_stride)<br>ret = acl.media.dvpp_set_pic_desc_height_stride(output_desc, output_height_stride)<br>ret = acl.media.dvpp_set_pic_desc_size(output_desc, out_buffer_size)<br># 9.执行异步色域转换,再调用acl.rt.synchronize_stream接口阻塞程序运行,直到指定Stream中的所有任务都完成。<br>ret = acl.media.dvpp_vpc_convert_color_async(dvpp_channel_desc, input_desc,<br> output_desc, stream)<br>ret = acl.rt.synchronize_stream(stream)<br># 10.色域转换结束后,释放资源,包括输入/输出图片的描述信息、输入/输出内存。<br>ret = acl.media.dvpp_destroy_pic_desc(input_desc)<br>ret = acl.media.dvpp_destroy_pic_desc(output_desc)<br>np_output = np.zeros(out_buffer_size, dtype=np.byte)<br>bytes_data = np_output.tobytes()<br>np_output_ptr = acl.util.bytes_to_ptr(bytes_data)<br># 将Device的处理结果数据传输到Host。<br>ret = acl.rt.memcpy(np_output_ptr, out_buffer_size, out_dev_buffer,<br> out_buffer_size, ACL_MEMCPY_DEVICE_TO_HOST)<br>ret = acl.media.dvpp_free(in_dev_buffer)<br>ret = acl.media.dvpp_free(out_dev_buffer)<br># 11.释放运行管理资源。<br>ret = acl.rt.destroy_stream(self.stream)<br>ret = acl.rt.destroy_context(self.context)<br>ret = acl.rt.reset_device(self.device_id)<br>ret = acl.finalize()<br># ......<br>

抠图(一图一框)示例代码

调用acl.media.dvpp_vpc_crop_async异步接口,按指定区域从输入图片中抠图,再将抠的图片存放到输出内存中,作为输出图片。

您可以从获取样例中获取完整样例代码。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>python<br>import acl<br># ......<br># 1.pyACL初始化。<br>ret = acl.init()<br># 2.运行管理资源申请,包括Device、Context、Stream。<br>self.device_id = 0<br>ret = acl.rt.set_device(self.device_id)<br>self.context, ret = acl.rt.create_context(self.device_id)<br>self.stream, ret = acl.rt.create_stream()<br># 3.指定抠图区域的位置、指定贴图区域的位置。<br># 按左上角为原点做偏移。w,h为图片原始宽高。<br>self.crop_area = acl.media.dvpp_create_roi_config(w // 2, w - 1, h // 2, h - 1)<br># 4.创建图片数据处理通道时的通道描述信息,dvpp_channel_desc 是acldvppChannelDesc类型。<br>self.dvpp_channel_desc = acl.media.dvpp_create_channel_desc()<br># 5.创建图片数据处理的通道。<br>ret = acl.media.dvpp_create_channel(self.dvpp_channel_desc)<br># 6.创建输入输出图片的描述信息,并设置各属性值。<br>self.input_desc = acl.media.dvpp_create_pic_desc()<br>assert self.input_desc is not None<br># 6.1 自定义方法 set_picture_desc 设置输入图片描述。<br># 根据计算公式计算内存大小存储图片数据,并设置到图片描述,同时设置其他属性。<br>self.set_picture_desc(self.input_desc, w, h, "input", 0)<br>self.output_desc = acl.media.dvpp_create_pic_desc()<br>assert self.output_desc is not None<br># 6.2 自定义方法 set_picture_desc 设置输出图片描述。<br>out_buffer_size = self.set_picture_desc(self.output_desc, w // 2, h // 2, "output", 0)<br># 7.执行异步抠图,再调用acl.rt.synchronize_stream接口阻塞Host运行,直到指定Stream中的所有任务都完成。<br>ret = acl.media.dvpp_vpc_crop_async(self.dvpp_channel_desc, self.input_desc, self.output_desc, self.crop_area, self.stream)<br>ret = acl.rt.synchronize_stream(self.stream)<br># 8.释放资源,包括输入/输出图片的描述信息、输入/输出内存、通道描述信息、通道等。<br>ret = acl.media.dvpp_destroy_pic_desc(self.input_desc)<br>ret = acl.media.dvpp_destroy_pic_desc(self.output_desc)<br># dev_buffer是字典对象,存储device侧申请内存。<br>for key in self.dev_buffer.keys():<br> if self.dev_buffer[key]:<br> ret = acl.media.dvpp_free(self.dev_buffer[key])<br>if self.dvpp_channel_desc:<br> ret = acl.media.dvpp_destroy_channel(self.dvpp_channel_desc)<br> assert ret == 0<br> ret = acl.media.dvpp_destroy_channel_desc(self.dvpp_channel_desc)<br> assert ret == 0<br># 9.释放运行管理资源。<br>ret = acl.rt.destroy_stream(self.stream)<br>ret = acl.rt.destroy_context(self.context)<br>ret = acl.rt.reset_device(self.device_id)<br># 10.pyACL去初始化。<br>ret = acl.finalize()<br># ......<br>

抠图缩放(一图一框)示例代码

  • 调用acl.media.dvpp_vpc_crop_resize_async异步接口,按指定区域从输入图片中抠图,再将抠的图片存放到输出内存中,作为输出图片。对于异步接口,还需调用acl.rt.synchronize_stream接口阻塞程序运行,直到指定Stream中的所有任务都完成。

    调用acl.media.dvpp_vpc_crop_resize_async接口实现抠图缩放时,支持指定缩放算法。

  • 输出图片区域与抠图区域“crop_area”不一致时会对图片再做一次缩放操作。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>python<br>import acl<br># ......<br># 1.pyACL初始化。<br>ret = acl.init()<br># 2.运行管理资源申请,包括Device、Context、Stream。<br>self.device_id = 0<br>ret = acl.rt.set_device(self.device_id)<br>self.context, ret = acl.rt.create_context(self.device_id)<br>self.stream, ret = acl.rt.create_stream()<br># 3.指定抠图区域的位置、指定贴图区域的位置。<br># 按左上角为原点做偏移。w,h为图片原始宽高。<br>self.crop_area = acl.media.dvpp_create_roi_config(w // 2, w - 1, h // 2, h - 1)<br># 4.创建图片数据处理通道时的通道描述信息,dvpp_channel_desc 是acldvppChannelDesc类型。<br>self.dvpp_channel_desc = acl.media.dvpp_create_channel_desc()<br># 5.创建图片数据处理的通道。<br>ret = acl.media.dvpp_create_channel(self.dvpp_channel_desc)<br># 6.创建输入输出图片的描述信息,并设置各属性值。<br>self.input_desc = acl.media.dvpp_create_pic_desc()<br>assert self.input_desc is not None<br># 6.1 自定义方法 set_picture_desc 设置输入图片描述。<br># 根据计算公式计算内存大小存储图片数据,并设置到图片描述,同时设置其他属性。<br>self.set_picture_desc(self.input_desc, w, h, "input", 0)<br>self.output_desc = acl.media.dvpp_create_pic_desc()<br>assert self.output_desc is not None<br># 6.2 自定义方法 set_picture_desc 设置输出图片描述。<br>resize_width = w // 4<br>resize_height = h // 4<br>out_buffer_size = self.set_picture_desc(self.output_desc, resize_width, resize_height, "output", 0)<br># 7.执行异步抠图,再调用acl.rt.synchronize_stream接口阻塞Host运行,直到指定Stream中的所有任务都完成。<br>self.resize_config = acl.media.dvpp_create_resize_config()<br>ret = acl.media.dvpp_vpc_crop_resize_async(self.dvpp_channel_desc, self.input_desc,<br> self.output_desc, self.crop_area, self.resize_config,<br> self.stream)<br>ret = acl.rt.synchronize_stream(self.stream)<br># 8.释放资源,包括输入/输出图片的描述信息、输入/输出内存、通道描述信息、通道等。<br>ret = acl.media.dvpp_destroy_pic_desc(self.input_desc)<br>ret = acl.media.dvpp_destroy_pic_desc(self.output_desc)<br># dev_buffer是字典对象,存储device侧申请内存。<br>for key in self.dev_buffer.keys():<br> if self.dev_buffer[key]:<br> ret = acl.media.dvpp_free(self.dev_buffer[key])<br>if self.dvpp_channel_desc:<br> ret = acl.media.dvpp_destroy_channel(self.dvpp_channel_desc)<br> assert ret == 0<br> ret = acl.media.dvpp_destroy_channel_desc(self.dvpp_channel_desc)<br> assert ret == 0<br># 9.释放运行管理资源。<br>ret = acl.rt.destroy_stream(self.stream)<br>ret = acl.rt.destroy_context(self.context)<br>ret = acl.rt.reset_device(self.device_id)<br># 10.pyACL去初始化。<br>ret = acl.finalize()<br># ......<br>

抠图贴图(一图一框)示例代码

  • 调用acl.media.dvpp_vpc_crop_and_paste_async异步接口,按指定区域从输入图片中抠图,再将抠的图片贴到目标图片的指定位置,作为输出图片。对于异步接口,还需调用acl.rt.synchronize_stream接口阻塞程序运行,直到指定Stream中的所有任务都完成。
  • 抠图区域“crop_area”的宽高与贴图区域“paste_area”宽高不一致时会对图片再做一次缩放操作。
  • 如果用户需要将目标图片读入内存用于存放输出图片,将贴图区域叠加在目标图片上,则需要编写代码逻辑:在申请输出内存后,将目标图片读入输出内存。

您可以从获取样例中获取完整样例代码。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>python<br>import acl<br># ......<br># 1.pyACL初始化。<br>ret = acl.init()<br># 2.运行管理资源申请,包括Device、Context、Stream。<br>self.device_id = 0<br>ret = acl.rt.set_device(self.device_id)<br>self.context, ret = acl.rt.create_context(self.device_id)<br>self.stream, ret = acl.rt.create_stream()<br># 3.指定抠图区域的位置、指定贴图区域的位置。<br># 按左上角为原点做偏移。w,h为图片原始宽高。<br>self.crop_area = acl.media.dvpp_create_roi_config(w // 2, w - 1, h // 2, h - 1)<br>self.paste_area = acl.media.dvpp_create_roi_config(w // 2, w - 1, h // 2, h - 1)<br># 4.创建图片数据处理通道时的通道描述信息,dvpp_channel_desc 是acldvppChannelDesc类型。<br>self.dvpp_channel_desc = acl.media.dvpp_create_channel_desc()<br># 5.创建图片数据处理的通道。<br>ret = acl.media.dvpp_create_channel(self.dvpp_channel_desc)<br># 6.创建输入输出图片的描述信息,并设置各属性值。<br>self.input_desc = acl.media.dvpp_create_pic_desc()<br>assert self.input_desc is not None<br># 6.1 自定义方法 set_picture_desc 设置输入图片描述。<br># 根据计算公式计算内存大小存储图片数据,并设置到图片描述,同时设置其他属性。<br>self.set_picture_desc(self.input_desc, w, h, "input", 0)<br>self.output_desc = acl.media.dvpp_create_pic_desc()<br>assert self.output_desc is not None<br># 6.2 自定义方法 set_picture_desc 设置输出图片描述。<br>out_buffer_size = self.set_picture_desc(self.output_desc, w, h, "output", 0)<br># 7.执行异步抠图粘贴,再调用acl.rt.synchronize_stream接口阻塞Host运行,直到指定Stream中的所有任务都完成。<br>ret = acl.media.dvpp_vpc_crop_and_paste_async(self.dvpp_channel_desc,<br> self.input_desc, self.output_desc,<br> self.crop_area, self.paste_area,<br> self.stream)<br>ret = acl.rt.synchronize_stream(self.stream)<br># 8.释放资源,包括输入/输出图片的描述信息、输入/输出内存、通道描述信息、通道等。<br>ret = acl.media.dvpp_destroy_pic_desc(self.input_desc)<br>ret = acl.media.dvpp_destroy_pic_desc(self.output_desc)<br># dev_buffer是字典对象,存储device侧申请内存。<br>for key in self.dev_buffer.keys():<br> if self.dev_buffer[key]:<br> ret = acl.media.dvpp_free(self.dev_buffer[key])<br>if self.dvpp_channel_desc:<br> ret = acl.media.dvpp_destroy_channel(self.dvpp_channel_desc)<br> assert ret == 0<br> ret = acl.media.dvpp_destroy_channel_desc(self.dvpp_channel_desc)<br> assert ret == 0<br># 9.释放运行管理资源。<br>ret = acl.rt.destroy_stream(self.stream)<br>ret = acl.rt.destroy_context(self.context)<br>ret = acl.rt.reset_device(self.device_id)<br># 10.pyACL去初始化。<br>ret = acl.finalize()<br># ......<br>

抠图贴图缩放(一图一框)示例代码

  • 调用acl.media.dvpp_vpc_crop_resize_paste_async异步接口,按指定区域从输入图片中抠图,再将抠的图片贴到目标图片的指定位置,作为输出图片。对于异步接口,还需调用acl.rt.synchronize_stream接口阻塞程序运行,直到指定Stream中的所有任务都完成。

    调用acl.media.dvpp_vpc_crop_resize_paste_async实现抠图缩放贴图时,支持指定缩放算法。

  • 抠图区域“crop_area”的宽高与贴图区域“paste_area”宽高不一致时会对图片再做一次缩放操作。

  • 如果用户需要将目标图片读入内存用于存放输出图片,将贴图区域叠加在目标图片上,则需要编写代码逻辑:在申请输出内存后,将目标图片读入输出内存。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br>74<br>75<br>76<br>77<br>78<br>79<br>80<br>python<br>import acl<br># ......<br># 1.pyACL初始化。<br>ret = acl.init()<br># 2.运行管理资源申请,包括Device、Context、Stream。<br>self.device_id = 0<br>ret = acl.rt.set_device(self.device_id)<br>self.context, ret = acl.rt.create_context(self.device_id)<br>self.stream, ret = acl.rt.create_stream()<br># 3.创建图片数据处理通道时的通道描述信息,dvpp_channel_desc 是acldvppChannelDesc类型。<br>self.dvpp_channel_desc = acl.media.dvpp_create_channel_desc()<br># 4.创建图片数据处理的通道。<br>ret = acl.media.dvpp_create_channel(self.dvpp_channel_desc)<br># 5.创建输出图片的描述信息,并设置各属性值。<br>self.output_desc = acl.media.dvpp_create_pic_desc()<br>assert self.output_desc is not None<br>out_buffer_size = self.set_picture_desc(self.output_desc, w // 2, h // 2, "output", 0)<br># 6.创建输入图片的描述信息,并设置各属性值。<br>self.input_desc = acl.media.dvpp_create_pic_desc()<br>assert self.input_desc is not None<br>self.set_picture_desc(self.input_desc, w, h, "input", 0)<br># 7.加载图片数据,并拷贝到Device侧。<br>np_yuv = np.fromfile(path, dtype=np.byte)<br>in_buffer_size = np_yuv.itemsize * np_yuv.size<br>bytes_data = np_yuv.tobytes()<br>np_yuv_ptr = acl.util.bytes_to_ptr(bytes_data)<br>ret = acl.rt.memcpy(self.dev_buffer["input_0"], in_buffer_size, np_yuv_ptr,<br> in_buffer_size, ACL_MEMCPY_HOST_TO_DEVICE)<br>assert ret == 0<br># 8.指定抠图、贴图区域的位置。<br>self.crop_area = acl.media.dvpp_create_roi_config(w // 2, w - 1, h // 2, h - 1)<br>self.paste_area = acl.media.dvpp_create_roi_config(w // 4, w // 2 - 1, h // 4, h // 2 - 1)<br># 9.执行异步抠图贴图缩放。<br>self.resize_config = acl.media.dvpp_create_resize_config()<br>ret = acl.media.dvpp_vpc_crop_resize_paste_async(self.dvpp_channel_desc,<br> self.input_desc, self.output_desc,<br> self.crop_area, self.paste_area,<br> self.resize_config, self.stream)<br>assert ret == 0<br>ret = acl.rt.synchronize_stream(self.stream)<br>assert ret == 0<br># 10.将输出数据拷贝到Host侧。<br>np_output = np.zeros(out_buffer_size, dtype=np.byte)<br>bytes_data = np_output.tobytes()<br>np_output_ptr = acl.util.bytes_to_ptr(bytes_data)<br>ret = acl.rt.memcpy(np_output_ptr, out_buffer_size, self.dev_buffer["output_0"],<br> out_buffer_size, ACL_MEMCPY_DEVICE_TO_HOST)<br>assert ret == 0<br># 11.释放资源,包括输入/输出图片的描述信息、输入/输出内存、通道描述信息、通道等。<br>ret = acl.media.dvpp_destroy_pic_desc(self.input_desc)<br>ret = acl.media.dvpp_destroy_pic_desc(self.output_desc)<br># dev_buffer是字典对象,存储device侧申请内存。<br>for key in self.dev_buffer.keys():<br> if self.dev_buffer[key]:<br> ret = acl.media.dvpp_free(self.dev_buffer[key])<br>if self.dvpp_channel_desc:<br> ret = acl.media.dvpp_destroy_channel(self.dvpp_channel_desc)<br> assert ret == 0<br> ret = acl.media.dvpp_destroy_channel_desc(self.dvpp_channel_desc)<br> assert ret == 0<br># 12.释放运行管理资源。<br>ret = acl.rt.destroy_stream(self.stream)<br>ret = acl.rt.destroy_context(self.context)<br>ret = acl.rt.reset_device(self.device_id)<br># 13.pyACL去初始化。<br>ret = acl.finalize()<br># ......<br>

抠图贴图(一图多框)示例代码

  • 调用dvpp_vpc_batch_crop_and_paste_async异步接口,按指定区域从输入图片中抠图,再将抠的图片贴到目标图片的指定位置,作为输出图片。对于异步接口,还需调用acl.rt.synchronize_stream接口阻塞程序运行,直到指定Stream中的所有任务都完成。
  • 抠图区域“crop_area”的宽高与贴图区域“paste_area”宽高不一致时会对图片再做一次缩放操作。
  • 如果用户需要将目标图片读入内存用于存放输出图片,将贴图区域叠加在目标图片上,则需要编写代码逻辑:在申请输出内存后,将目标图片读入输出内存。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br>74<br>75<br>76<br>77<br>78<br>79<br>80<br>81<br>82<br>83<br>84<br>85<br>86<br>87<br>python<br>import acl<br># ......<br># 1.pyACL初始化。<br>ret = acl.init()<br># 2.运行管理资源申请,包括Device、Context、Stream。<br>self.device_id = 0<br>ret = acl.rt.set_device(self.device_id)<br>self.context, ret = acl.rt.create_context(self.device_id)<br>self.stream, ret = acl.rt.create_stream()<br># 3.创建图片批处理输入输出描述。<br>self.out_batch_pic_desc = acl.media.dvpp_create_batch_pic_desc(self.out_batch_size)<br>self.in_batch_pic_desc = acl.media.dvpp_create_batch_pic_desc(self.in_batch_size)<br># 3.1 指定批量抠图区域的位置、指定批量贴图区域的位置。<br># 3.2 设置输入输出图片描述:如果抠图贴图的输出图片作为模型推理的输入,则输出图片的宽高要与模型要求的宽高保持一致。<br>for i in range(self.in_batch_size):<br> input_desc = acl.media.dvpp_get_pic_desc(self.in_batch_pic_desc, i)<br> assert input_desc is not None<br> # 申请内存并设置输出图片描述。<br> self.set_picture_desc(input_desc, w, h, "input", i)<br> # copy from host to device.<br> key = "input" + '_' + str(i)<br> ret = acl.rt.memcpy(self.dev_buffer[key], in_buffer_size, np_yuv_ptr,<br> in_buffer_size, 1)<br> assert ret == 0<br> # 创建roiNums,每张图对应需要抠图和贴图的数量。<br> roiList.append(self.out_batch_size // self.in_batch_size)<br>for i in range(self.out_batch_size):<br> output_desc = acl.media.dvpp_get_pic_desc(self.out_batch_pic_desc, i)<br> assert output_desc is not None<br> # 自定义方法申请内存并设置输出图片描述。<br> self.set_picture_desc(output_desc, w, h, "output", i)<br> if i == 0:<br> crop_area = acl.media.dvpp_create_roi_config(w // 2, w - 1, h // 2, h - 1)<br> else:<br> crop_area = acl.media.dvpp_create_roi_config(0, w - 1, h // 2, h - 1)<br> paste_area = acl.media.dvpp_create_roi_config(w // 2, w - 1, h // 2, h - 1)<br> self.cropList.append(crop_area)<br> self.pasteList.append(paste_area)<br># 3.3 roiList,每张图对应需要抠图和贴图的数量。输出图片数相对输入多出来的,加到最后一张输入图片的输出。<br>total_num = 0<br>for i in range(self.in_batch_size):<br> total_num += roiList[i]<br>if self.out_batch_size % self.in_batch_size != 0:<br> roiList[-1] = self.out_batch_size - total_num + roiList[-1]<br># 4.创建图片数据处理通道时的通道描述信息,dvppChannelDesc_是acldvppChannelDesc类型。<br>self.dvpp_channel_desc = acl.media.dvpp_create_channel_desc()<br># 5.创建图片数据处理的通道。<br>ret = acl.media.dvpp_create_channel(self.dvpp_channel_desc)<br># 6.执行异步缩放,再调用acl.rt.synchronize_stream接口阻塞程序运行,直到指定Stream中的所有任务都完成。<br>_, ret = acl.media.dvpp_vpc_batch_crop_and_paste_async(self.dvpp_channel_desc, self.in_batch_pic_desc,<br> roiList, self.out_batch_pic_desc, self.cropList,<br> self.pasteList, self.stream)<br>ret = acl.rt.synchronize_stream(self.stream)<br># 7.释放资源,包括输入/输出图片的描述信息、输入/输出内存、通道描述信息、通道等。<br># 7.1 释放图片描述和批量图片描述。<br>self._free_pic_desc()<br>for i in range(len(self.cropList)):<br> ret = acl.media.dvpp_destroy_roi_config(self.cropList[i])<br> assert ret == 0<br>for i in range(len(self.pasteList)):<br> ret = acl.media.dvpp_destroy_roi_config(self.pasteList[i])<br> assert ret == 0<br>for key in self.dev_buffer.keys():<br> if self.dev_buffer[key]:<br> ret = acl.media.dvpp_free(self.dev_buffer[key])<br># 7.2 销毁通道和通道描述。<br>if self.dvpp_channel_desc:<br> ret = acl.media.dvpp_destroy_channel(self.dvpp_channel_desc)<br> assert ret == 0<br> ret = acl.media.dvpp_destroy_channel_desc(self.dvpp_channel_desc)<br> assert ret == 0<br># 8.释放运行管理资源。<br>ret = acl.rt.destroy_stream(self.stream)<br>ret = acl.rt.destroy_context(self.context)<br>ret = acl.rt.reset_device(self.device_id)<br>9.pyACL去初始化。<br>ret = acl.finalize()<br># ......<br>

父主题: 媒体数据处理V1

在线提单