虹软人脸识别3.0 - 图像数据结构介绍(Android)

发布时间:2020-08-04 18:44:07 作者:丸子丸子丸子
来源:ITPUB博客 阅读:186

从虹软开放了2.0版本SDK以来,由于具有免费、离线使用的特点,我们公司在人脸识别门禁应用中使用了虹软SDK,识别效果还不错,因此比较关注虹软SDK的官方动态。近期上线了ArcFace 3.0 SDK版本,确实做了比较大的更新。首先本篇介绍一下关于Android平台算法的更新内容。

在实际开发过程中使用新的图像数据结构具有一定的难度,本文将从以下几点对该图像数据结构及使用方式进行详细介绍

  1. SDK接口变动

  2. ArcSoftImageInfo类解析

  3. SDK相关代码解析

  4. 步长的作用

  5. 将Camera2回传的Image转换为ArcSoftImageInfo

一、SDK接口变动

在接入3.0版SDK时,发现 FaceEngine类中的 detectFacesprocessextractFaceFeature等传入图像数据的函数都有重载函数,重载函数的接口均使用 ArcSoftImageInfo对象作为入参的图像数据,以人脸检测为例,具体接口如下:

原始接口:

public int detectFaces(byte[] data, int width, int height, int format, List<FaceInfo> faceInfoList)

新增接口:

public int detectFaces(ArcSoftImageInfo arcSoftImageInfo, List<FaceInfo> faceInfoList)

可以看到,重载函数传入 ArcSoftImageInfo对象作为图像数据进行检测, arcSoftImageInfo替代了原来的 data, width, height, format

二、ArcSoftImageInfo类解析

在我实际使用后发现, ArcSoftImageInfo不只是简单封装一下,它还将一维数组 data修改为二维数组 planes,还新增了一个与 planes对应的步长数组 strides

步长概念介绍:
步长可以理解为一行像素的字节数。

类结构如下:

public class ArcSoftImageInfo {
    private int width;
    private int height;
    private int imageFormat;
    private byte[][] planes;
    private int[] strides;
    ...
}

官方文档中对该类的介绍:

类型 变量名 描述
int width 图像宽度
int height 图像高度
int imageFormat 图像格式
byte[][] planes 图像通道
int[] strides 每个图像通道的步长
// arcSoftImageInfo组成方式举例:
// NV21格式数据,有两个通道,
// Y通道步长一般为图像宽度,若图像经过8字节对齐、16字节对齐等操作,需填入对齐后的图像步长
// VU通道步长一般为图像宽度,若图像经过8字节对齐、16字节对齐等操作,需填入对齐后的图像步长
ArcSoftImageInfo arcSoftImageInfo = new ArcSoftImageInfo(width, height, FaceEngine.CP_PAF_NV21, new byte[][]{planeY, planeVU}, new int[]{yStride, vuStride});
// GRAY,只有一个通道,
// 步长一般为图像宽度,若图像经过8字节对齐、16字节对齐等操作,需填入对齐后的图像步长
arcSoftImageInfo = new ArcSoftImageInfo(width, height, FaceEngine.CP_PAF_GRAY, new byte[][]{gray}, new int[]{grayStride});
// BGR24,只有一个通道,
// 步长一般为图像宽度的三倍,若图像经过8字节对齐、16字节对齐等操作,需填入对齐后的图像步长
arcSoftImageInfo = new ArcSoftImageInfo(width, height, FaceEngine.CP_PAF_BGR24, new byte[][]{bgr24}, new int[]{bgr24Stride});
// DEPTH_U16,只有一个通道,
// 步长一般为图像宽度的两倍,若图像经过8字节对齐、16字节对齐等操作,需填入对齐后的图像步长
arcSoftImageInfo = new ArcSoftImageInfo(width, height, FaceEngine.CP_PAF_DEPTH_U16, new byte[][]{depthU16}, new int[]{depthU16Stride});

可以看到, ArcSoftImageInfo用于存储分离的图像数据,以 NV21数据为例, NV21数据有两个通道,那二维数组 planes存储的就是两个数组: y数组和 vu数组。以下是 NV21数据的排列方式:

NV21图像格式属于 YUV颜色空间中的 YUV420SP格式,每四个Y分量共用一组U分量和V分量,Y连续存储,U与V交叉存储。

排列方式如下(以8x4的图像为例):

Y Y   Y Y   Y Y   Y Y

Y Y   Y Y   Y Y   Y Y

Y Y   Y Y   Y Y   Y Y

Y Y   Y Y   Y Y   Y Y

V U  V U   V U  V U

V U  V U   V U  V U

以上数据分为两个通道,首先是连续的 Y数据,然后是交叉存储的 VU数据。如果我们使用的是 Camera API,那基本用不到 ArcSoftImageInfo类,因为 Camera API回传的 NV21数据是连续的,直接使用旧版接口即可;而当我们使用的是其他API时,拿到的数据可能是不连续的,例如使用 Camera2 APIMediaCodec拿到的 android.media.Image类对象,其图像数据也是分通道的,我们可以根据其通道内容,获取 Y通道数据和 VU通道数据,组成 NV21格式的 ArcSoftImageInfo对象用于处理。

三、SDK相关代码解析

我们来看下SDK中判断图像数据是否合法的校验代码:

注:原始代码由于被编译器修改过,阅读体验不佳,以下代码是我修改过的,将常量值替换回常量名,更便于阅读。

只是差了这几个像素,为什么就导致人脸检测不到了呢?之前说到过,步长可以理解为一行像素的字节数。如果第一行像素的读取有偏差,那后续像素的读取也会受到影响。

以下是对一张大小为 1000x554NV21图像数据,以不同步长进行解析的结果:

以正确的步长解析 以错误的步长解析
虹软人脸识别3.0 - 图像数据结构介绍(Android) 虹软人脸识别3.0 - 图像数据结构介绍(Android)

可以看到,对于一张图像,如果使用了错误的步长去解析,我们可能就无法看到正确的图像内容。

结论:通过引入图像步长能够有效的避免高字节对齐的问题。

五、将Camera2回传的Image转换为ArcSoftImageInfo

以上代码中便是 Camera2 API回传的数据转换为 ArcSoftImageInfo对象并检测的具体实现。以下是将 YUV数据组成 ArcSoftImageInfo对象的具体实现。

六、ArcSoftImageInfo优点总结

  1. 在获取的图像数据源是分通道的数据时,使用 ArcSoftImageInfo对象传入分离的图像数据可避免数据拼接所需的额外内存消耗。
  2. 引入了步长的概念,在使用时传入了各个通道的步长,使开发者在使用SDK时对图像数据的了解更清晰。

Android Demo可在 虹软人脸识别开放平台下载

推荐阅读:
  1. 浅谈Android项目----JSON解析(4种解析技术详解)
  2. Android开发中打开一个activity并返回数据的方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

android 人脸 介绍

上一篇:选择软件开发平台,“快速开发”是关键

下一篇:Nginx参数proxy_pass细说

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》