“打破沙锅问到底”之“resize”

书接上回,在学习过JPEGD的样例之后,再来看resize的样例,之前提到过的这里就不再赘述,多关注功能本身是怎么实现的

图片缩放的开源样例

https://gitee.com/ascend/samples/tree/master/cplusplus/level2_simple_inference/0_data_process/resize

sample_build.sh中下载的图片是wood_rabbit_1024_1068_nv12.yuv

sample_run.sh中run命令是

./main ../data/wood_rabbit_1024_1068_nv12.yuv 1024 1068 ./output/output.yuv 224 224

第0个参数 ./main

第1个参数 ../data/wood_rabbit_1024_1068_nv12.yuv

第2个参数 1024

第3个参数 1068

第4个参数 ./output/output.yuv

第5个参数 224

第6个参数 224

参考main.cpp分析参数的意义

main第166行调用Initparam()函数解析参数

Initparam第43-45行,尝试打开目录“./output”,如果目录流为空指针,即该目录不存在时,创建目录“./output”

Initparam第46-49行,检查是否传入7个参数

Initparam第50-56行,将第2个参数1024通过atoi()函数转为int类型,保存在inw中;以此类推

inw=1024 输入图片宽

inh=1068 输入图片高

outw=224 输出图片宽

outh=224 输出图片高

inPicDesc={../data/wood_rabbit_1024_1068_nv12.yuv, 1024, 1068} 输入图片描述信息

outPicDesc={./output/output.yuv, 224, 224} 输出图片描述信息

熟悉所有参数之后再来看main.cpp中的main函数

main第154-157行,调用aclInit函数进行初始化

main第159-163行,调用aclrtSetDevice函数初始化device,调用aclrtCreateContext函数初始化context,调用aclrtCreateStream函数初始化Stream,调用aclrtGetRunMode函数获取运行模式为ACL_HOST

为了验证运行模式,我在main.cpp加入了一段打印信息的代码,确认runMode为ACL_HOST

main第166-168行,调用Initparam函数,如前所述解析参数并定义整型常量ModelInputWidth和ModelInputHeight分别描述待缩放图片的宽高

main第171行,调用acldvppCreateChannelDesc函数,创建通道描述符dvppChannelDesc_

main第174行,调用acldvppCreateChannel函数,创建通道

main第177-178行调用ReadBinFile函数

ReadBinFile第89-93行调用ifstream函数,以二进制文件方式打开yuv文件,并检查是否成功打开

ReadBinFile第95行调用seekg函数,从文件末尾位置binFile.end偏移0个单位

ReadBinFile第96-101行调用tellg函数返回当前文件流位置,即文件大小,并定义整型变量binFileBufferLen存放文件大小,然后检查文件是否为空

ReadBinFile第103行调用seekg函数,从文件开始位置binFile.beg偏移0个单位

ReadBinFile第105-110行调用new函数,分配一个char数组,数组中共有binFileBufferLen个char元素,并返回指向第一个char的指针,让指针binFileBufferData指向数组第一个char

ReadBinFile第111行调用read函数,从流当前位置(文件开始位置)开始,读取binFileBufferLen个char,并将其存入binFileBufferData指针所指的位置

ReadbinFile第112行调用close函数关闭读取文件的流

ReadbinFile第113行将binFileBufferLen作为文件大小传递给fileSize,即main中的inputBuffSize

ReadbinFile第114行返回缓存首地址指针binFileBufferData给main中的inputBuff

回到main函数

main第180行根据host侧的内存大小inputBuffSize定义device侧的缓存大小inBufferSize

main第181行调用acldvppMalloc函数,根据inBufferSize,在device侧申请内存,并用指针inBufferDev指向申请到的内存首地址

main第182-187行,由于runMode是ACL_HOST,所以触发if分支,调用aclrtMemcpy函数,将host侧源位置inputBuff上大小为inputBufferSize的内容,复制到device侧位置从inBufferDev开始大小为inBufferSize的内存上

main第188行删除host侧的内存inputBuff

main第190行调用acldvppCreateResizeConfig函数,创建用于存放图片缩放配置数据的变量resizeConfig_

main第193-194行从解析得到的参数中提取原图片宽高信息

main第199-200行,调用AlignmentHelper函数进行对齐,宽对齐到128,高对齐到16,得到对齐后的图片宽高

main第201行根据对齐后的原图宽高计算对齐后的原图内存大小,并存放在inputBufferSize中,该计算公式可从文档中查到

main第202-203行分别创建缩放前后的图片描述符vpcInputDesc和vpcOutputDesc

main第204-212行调用acldvppSetPicDesc系列函数为图片描述符vpcInputDesc_设置参数

其中main第205行提供device侧缓存的地址指针inBufferDev,并以char类型作为读取方式,读取device侧图片数据

然后,指定图片格式、原图宽高、对齐后宽高、缩放前对齐后图片内存大小

main第215-216行调用AlignmentHelper函数进行对齐,将缩放后的目标宽度对齐到16,缩放后的目标宽度对齐到2,详情参见文档约束说明

main第217行根据对齐后的缩放后的宽高计算缩放后输出图片的内存大小,并存放在outputBufferSize中,该计算公式可从文档中查到

main第218行调用aclrtMalloc函数,在device侧申请大小为vpcOutBufferSize的内存,用于存放缩放后的数据

main第219-228行调用acldvppSetPicDesc系列函数为图片描述符vpcOutputDesc_设置参数,设置了图片内存、格式、目标宽高、对齐后的目标宽高、缩放后对齐后图片内存大小

main第230-235行,调用acldvppVpcResizeAsync函数,传入通道描述符dvppChannelDesc_,传入缩放前输入图片描述符vpcInputDesc_,传入缩放后输出图片描述符vpcOutputDesc_,传入图片缩放配置数据resizeConfig_,传入流stream_,执行异步缩放

main第237-241行,调用aclrtSynchronizeStream函数,阻塞程序直到流stream_内所有操作完成

main第244-252行,释放图片缩放配置数据、释放缩放前输入图片描述符、释放缩放后输出图片描述符、释放device侧缩放前数据缓存

main第254-258行,调用SaveDvppOutputData函数,将device侧的数据搬运到host侧,并保存成输出图片yuv文件

main第259-261行,释放通道、释放通道描述符

main第263行调用DestroyResource函数,释放stream、释放context、释放device、调用aclFinalize去初始化

至此,main.cpp结束

最后,附上文档中对resize流程的描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值