更新时间:2021-03-18 GMT+08:00
分享

抠图贴图

基本原理

  • 调用acldvppCreateChannel接口创建图片数据处理的通道。
  • 调用acldvppVpcCropAndPasteAsync异步接口,按指定区域从输入图片中抠图,再将抠的图片贴到目标图片的指定位置,作为输出图片。对于异步接口,还需调用aclrtSynchronizeStream接口阻塞Host运行,直到指定Stream中的所有任务都完成。
  • 抠图区域cropArea的宽高与贴图区域pasteArea宽高不一致时会对图片再做一次缩放操作。
  • 如果用户需要将目标图片读入内存用于存放输出图片,将贴图区域叠加在目标图片上,则需要编写代码逻辑:在申请输出内存后,将目标图片读入输出内存。

示例代码

您可以从acl_vpc_jpege_resnet50样例的“src/sample_process.cpp”“src/dvpp_process.cpp”“src/utils.cpp”文件中查看完整样例代码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "acl/acl.h"
#include "acl/ops/acl_dvpp.h"
//1.ACL初始化
const char *aclConfigPath = "../src/acl.json";
aclError ret = aclInit(aclConfigPath);

//2.运行管理资源申请,包括Device、Context、Stream
ret = aclrtSetDevice(deviceId_);
ret = aclrtCreateContext(&context_, deviceId_);
ret = aclrtCreateStream(&stream_);

//3. 指定抠图区域的位置、指定贴图区域的位置,cropArea_和pasteArea_是acldvppRoiConfig类型
cropArea_ = acldvppCreateRoiConfig(512, 711, 512, 711);
pasteArea_ = acldvppCreateRoiConfig(16, 215, 16, 215);

//4. 创建图片数据处理通道时的通道描述信息,dvppChannelDesc_是acldvppChannelDesc类型
dvppChannelDesc_ = acldvppCreateChannelDesc();

//5. 创建图片数据处理的通道。
aclError ret = acldvppCreateChannel(dvppChannelDesc_);

//6. 申请输入内存vpcInDevBuffer_,内存大小vpcInBufferSize根据计算公式得出
//如果将其它操作(例如,解码)的输出内存作为抠图贴图的输入,则无需单独申请输入内存
//ret = acldvppMalloc(&vpcInDevBuffer_, vpcInBufferSize)
//7. 申请输出内存vpcOutBufferDev_,内存大小vpcOutBufferSize_根据计算公式得出
ret = acldvppMalloc(&vpcOutBufferDev_, vpcOutBufferSize_)

//8. 创建输入图片的描述信息,并设置各属性值
//此处示例将解码的输出内存作为抠图贴图的输入,vpcInputDesc_是acldvppPicDesc类型
vpcInputDesc_ = acldvppCreatePicDesc();
acldvppSetPicDescData(vpcInputDesc_, decodeOutBufferDev_); 
acldvppSetPicDescFormat(vpcInputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
acldvppSetPicDescWidth(vpcInputDesc_, inputWidth_);
acldvppSetPicDescHeight(vpcInputDesc_, inputHeight_);
acldvppSetPicDescWidthStride(vpcInputDesc_, jpegOutWidthStride);
acldvppSetPicDescHeightStride(vpcInputDesc_, jpegOutHeightStride);
acldvppSetPicDescSize(vpcInputDesc_, jpegOutBufferSize);

//9. 创建输出图片的描述信息,并设置各属性值
//如果抠图贴图的输出图片作为模型推理的输入,则输出图片的宽高要与模型要求的宽高保持一致
//vpcOutputDesc_是acldvppPicDesc类型
vpcOutputDesc_ = acldvppCreatePicDesc();
acldvppSetPicDescData(vpcOutputDesc_, vpcOutBufferDev_);
acldvppSetPicDescFormat(vpcOutputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
acldvppSetPicDescWidth(vpcOutputDesc_, dvppOutWidth);
acldvppSetPicDescHeight(vpcOutputDesc_, dvppOutHeight);
acldvppSetPicDescWidthStride(vpcOutputDesc_, dvppOutWidthStride);
acldvppSetPicDescHeightStride(vpcOutputDesc_, dvppOutHeightStride);
acldvppSetPicDescSize(vpcOutputDesc_, vpcOutBufferSize_);

//10. 执行异步缩放,再调用aclrtSynchronizeStream接口阻塞Host运行,直到指定Stream中的所有任务都完成
ret = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_,
        vpcOutputDesc_, cropArea_, pasteArea_, stream_);
ret = aclrtSynchronizeStream(stream_);

//11. 解码结束后,释放资源,包括输入/输出图片的描述信息、输入/输出内存、通道描述信息、通道等
acldvppDestroyPicDesc(vpcInputDesc_);
acldvppDestroyPicDesc(vpcOutputDesc_);
//(void)acldvppFree(vpcInDevBuffer_);
(void)acldvppFree(vpcOutBufferDev_);
acldvppDestroyChannel(dvppChannelDesc_);
(void)acldvppDestroyChannelDesc(dvppChannelDesc_);
dvppChannelDesc_ = nullptr;

//....
分享:

    相关文档

    相关产品

close