如何利用 CANN DVPP 进行图片的等比例缩放?
本文分享自华为云社区《CANN DVPP进行图片的等比例缩放》,作者:马城林 。
1. 为什么需要进行等比例的缩放,直接暴力缩放成模型需要的宽高岂不是更省事
首先没有任何的规定表示我们必须进行等比例的缩放,因为实际上即使图像上的物体因为缩放而变形,物体本身的特征还是存在,神经网络依旧可以提取对应的特征进而预测出物体的位置,通过计算实际的宽高与模型之间的宽高的比例依旧可以将模型预测到的候选框的映射到实际的原图上。这样看来等比例的缩放存在感好低!
但是事情真的是这样吗?肯定不是呀,要不我为啥会写这篇博客呢?
首先有以下几点考虑:
目标检测除了将图像送入模型,实际上物体在图像中的位置也被作为一部分信息参与了模型的训练,经过等比例缩放的图片在坐标转换上明显省事。
有些图像经过非等比例压缩后已经与实际场景中的物体差别很大,严重的变形会干扰到模型的准确性。
等比例缩放更加符合我们人类的直觉。
2. 如何在昇腾 AI 处理器上进行等比例缩放
如果在我们的训练服务器,或者我们自己的个人计算机上,因为计算能力的相对充沛,我们可以借助很多开源图像库例如 opencv,pillow 等进行图像的等比例缩放。但是一旦道路端侧部署时这些开源图像库的方法往往成为整个推理过程最耗时的部分,因为他们主要通过 CPU 进行运算,而在诸如 200DK 这样的环境上,进行这样的变换让本就不充沛的 CPU 算力雪上加霜。而昇腾 AI 处理器上拥有专门处理数字图像的硬件单元。所以如何借助这些专用的硬件单元是十分重要的。话不多说开始吧!
3. 实战讲解
主要从以下几个方面进行讲解
步骤分解
每一步在昇腾 AI 处理器上的实现
怎么把几步组合起来完成一个完整的动作
介绍 AscendCL 为开发者提供的组合 API 接口,只需要一个函数完成所有动作,想想都刺激
<概念注意>
昇腾 AI 处理器在不同的环境上拥有不同运行模式,常见的分为两种,一种是类似于显卡一样插在服务器的 PCIE 插槽上,提供加速服务,一种是类似于 200DK 一样的嵌入式环境。
工作在服务器的 PCIE 插槽上的昇腾 310 内存有两种存在形态,一种就是我们常见的内存,称为 host 内存。一种类似于显卡的显存,称为 device 内存,这种状态下需要涉及到内存拷贝的问题。
200DK 这种环境,不区分 host 与 device,只有一块 device 内存,所以并不涉及 host 与 device 的内存拷贝问题
媒体数据处理描述图形的大小,主要有两种表示方法,width,height,表示图像的真实宽高,widthstride,heightstride 表示图像在内存中对其到 128,16,2 后的宽高,内存宽高标识图像在内存中的位置(但是可能有为了填充而产生的无效数据),真实宽高就标识内存中真实有效的数据。
JPEG Decode 时对 JPEG 的源图像没有宽高的要求,但是输出的数据,宽会对齐到 128,长会对齐到 16,对齐后可能会产生一部分的无效数据。
VPC 图像缩放,抠图,贴图对输入的源图像宽高对齐到 2,对齐后的内存宽高为,宽对齐到 16,高对齐到 2,输出与输入约束条件相同
JPEG Encode 对输入的源图像宽高对齐到 2,对齐后的内存宽高为,宽对齐到 16 或者 16 的倍数(128 时性能更好),高对齐到 16。
详细的约束对齐规则
3.1 步骤分解
很多朋友和我一样属于一听就会,一动手就废的类型,在脑海里勾勒出万里江山,实际一上手,我是个傻子。
实际上是我们还没有掌握做事情的诀窍,就是把事情分解成可以很方便用代码描述出的步骤;计算机编程让人感到头皮发麻的一个重要原因就是计算机它只会一步一步来,不会跳步。所以我们脑海里面很简单的步骤在编程实现后也可能代码很长。
1、将常见的 JPEG 图片解码成 YUV 格式的图片
2、因为 JPEG 解码有 128x16 的对齐要求,所以解码后的数据边缘会出现无效数据,需要进行裁剪
3、进行 resize 的操作,没有对应的等比例缩放的接口,但是如果我们最后指定的图像大小相对于原图是等比例的,就是等比例缩放。
4、进行等比例缩放时需要一个,与模型大小一致的纯色背景图片作为贴图的背景,我们可以申请对应大小的一些区域然后,将对应区域全部赋值为同一个数。
5、进行贴图
6、进行模型推理或编码保存
3.2 对应的变量怎么声明与初始化
DVPP 处理的通道的声明与销毁
DVPP 的一系列操作都是建立在已经声明初始化的通道上,你可以理解为初始化了相关的硬件资源
各种图像的操作描述对应的图像的描述信息的创建与销毁
申请内存
创建抠图,贴图的区域
不知道图片的相关信息获取信息的接口
图像缩放,贴图,抠图相关的接口(当有多个操作动作时建议使用组合接口,虽然看似是多个步骤,实际上硬件内部只是执行一次操作可以大幅度提升处理的效率)
3.3 实战讲解
效果展示:1024x688 =》 416x416
开始进行解码操作
开始进行抠图的操作,因为我们这次需要执行抠图+缩放+贴图三个动作所以我们选择组合 API 进行编程
完成了一系列的操作
总结
对于 DVPP 处理来说,单独的接口调用需要全部满足输入和输出的长宽以及对齐的要求
但是对于 JPEG+VPC 这样的串联编程来说前一个组件的输出图像描述是后一个组件的输入描述,设定对齐内存是为了有效标定,图像在内存中的位置,如果固执的设定对齐后的值,对于后一个组件来说很有可能得到的输入是有缺失的信息。
根据众多对齐要求我们可以看出,对于图像的原始宽高全部 2 对齐是一个比较好的习惯,而且常用的图像规格都是偶数例如 1920x1080,1280x720, 640x640, 416x416,最好不要出现长或者宽为奇数的情况,因为硬件会自动为奇数进行对齐从而产生无效数据。增加了处理的难度。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/07c0ca839399bb850d128ba6f】。文章转载请联系作者。
评论