人证比对在如今的社会中随处可见,如高铁、飞机、酒店入住、甚至景区入口都可以看到各种各样的人证应用,人脸识别SDK的也如雨后春笋一般层出不穷,如百度、商汤、Face++、虹软等。在尝试使用各家的SDK之后,最让我青睐的要数虹软科技的SDK了,最直接的一个原因就是虹软承诺永久免费。我从2.0版本开始就在使用了,实测效果确实不错,就在上个月收到消息ArcFace3.0更新了,作为一个白嫖党自然不会错过这次的更新,在上手了3.0 之后,发现ArcFace 3.0有以下新特性。
-
特征比对支持比对模型选择,有生活照比对模型和人证比对模型
-
Android平台新增64位的SDK
-
新增了一种图像数据传入方式
本文将根据以下几点对ArcFace3.0的人证场景使用进行介绍
-
ArcFace 3.0 SDK接口变动的得与失
-
如何将人证 2.0 Demo程序改为搭载ArcFace
3.0 SDK的程序 -
如何直接把ArcFace 3.0的demo修改为人证程序
一、ArcFace 3.0 SDK接口变动的得与失
接口变动的优势:
1.业务自由度变高
以人证 2.0为例,我们只能传入数据、传出结果,而一些中间产物,例如人脸特数据征就获取不到了。现在采用ArcFace 3.0之后,取消了固定的流程,检测、比对、提取等流程都可以由自己控制。
2.可以在同一个工程内实现生活照比对与人证比对
人证 SDK与ArcFace
SDK 存在冲突,无法同时使用,若我们既想用人证又想用生活照,就要写两个工程,并且两个工程的流程还有些不同。而现在只需要接口内选择模型就可以实现模型的切换,完全可以在一个工程内实现人证与生活照程序的集成。
3.代码复用性
ArcFace 3.0中人证与身份证区别只有compare接口中的模型选择,其他完全一致,因此大部分的代码都可以复用,大大提高了开发的效率。
接口变动的缺点:
1.接口变动
万事有得必有失,由于ArcFace 3.0没有关于人证部分的封装,致使在升级过程中所有的接口都需要变更,相信也是所有程序员都不愿意看到的问题。
2.实现变困难
同样由于ArcFace 3.0没有关于人证部分的封装,使得原本接口中自带的一些流程与回调需要自己来实现,这对于刚上手的人来说,不是十分友好。
小结:
虽然上面说了一些ArcFace 3.0的缺点,但是我本人还是很赞成这次的升级,毕竟每个产品的革新总会带来一些冲击,但是相对于这些冲击来说,我相信接口、识别流程的统一为程序的适用性与业务的自由性都提高了,相信对于人证2.0来说这次“壮士断腕”的举措长远来看是值得的。
二、人证 2.0 Demo集成ArcFace 3.0
SDK
在上面我们看到了由于接口的变动,致使人证2.0程序所有的接口都要修改,接下来我将以人证2.0
Demo为例,讲解一下我是如何使用ArcFace 3.0 SDK进行升级的。
1、人证 2.0 Demo工程配置
考虑到可能有些用户对人证 2.0 Demo不太熟悉,先简单介绍一下官方Demo如何配置使用。
首先,先将人证引擎如图所示放入demo内,接下来修改Constants内的APP_ID与SDK_KEY,APP_ID与SDK_KEY以及人证引擎均由官网的开放平台上进行获取。然后在设备的SDCard根目录下放置一张命名为“sample.jpg”的图片做为模拟人证输入的图片(图片路径可以在MainActivity下的SAMPLE_FACE变量内进行修改),下图为配置完毕后运行的截图。
2.ArcFace 3.0 SDK替换
首先我们要先获取ArcFace3.0的SDK,同样可以在开放平台上进行获取。用新的SDK库替换掉原本的SDK,替换后的项目目录如下图所示
3.ArcFace3.0接口替换
上面提到了,由于3.0的全面变更,所有的接口全部都发生了改变,因此我们要把原本2.0的接口全部替换为3.0。
3.1 引擎激活:
激活方面接口参数没有任何变化
人证 2.0 :
IdCardVerifyManager.getInstance().active(Context context, String appId, String
sdkKey);
ArcFace 3.0 :
FaceEngine.active(Context context, String appId, String sdkKey);
3.2 引擎初始化:
从初始化开始,人证 2.0与ArcFace3.0接口有了较大的区别,人证 2.0有对Id Card信息与Camera信息监听,而3.0取消了这个监听机制,接口内的参数就不一一介绍了,官方文档介绍的非常详细,大家可以去参考一下官方文档。
人证 2.0 :
IdCardVerifyManager.getInstance().init(Context context, IdCardVerifyListener
listener)
ArcFace 3.0 :
FaceEngine.init(Context context, DetectMode detectMode,
DetectFaceOrientPriority detectFaceOrientPriority, int detectFaceScaleVal, int
detectFaceMaxNum, int combinedMask)
3.3 激活&初始化demo:
下面是我对2.0进行替换后的前后代码,可以给大家做一个参考:
人证 2.0 :
private void initEngine() {
int result =
IdCardVerifyManager.getInstance().init(this, idCardVerifyListener);
LogUtils.dTag(TAG,
"initResult: " + result);
if (result ==
IdCardVerifyError.MERR_ASF_NOT_ACTIVATED) {
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
int activeResult =
IdCardVerifyManager.getInstance().active(
MainActivity.this,
APP_ID, SDK_KEY);
runOnUiThread(new
Runnable() {
@Override
public void run()
{
LogUtils.dTag(TAG, "activeResult: " + activeResult);
if (activeResult ==
IdCardVerifyError.OK) {
int
initResult = IdCardVerifyManager.getInstance().init(
MainActivity.this, idCardVerifyListener);
LogUtils.dTag(TAG, "initResult: "
+ initResult);
if
(initResult != IdCardVerifyError.OK) {
toast("人证引擎初始化失败,错误码: " +
initResult);
}
} else {
toast("人证引擎激活失败,错误码: " +
activeResult);
}
}
});
}
});
} else if (result !=
IdCardVerifyError.OK) {
toast("人证引擎初始化失败,错误码: " + result);
}
}
ArcFace 3.0 :
private void initEngine() {
int result =
faceEngine.init(this, DetectMode.ASF_DETECT_MODE_VIDEO,
DetectFaceOrientPriority.ASF_OP_ALL_OUT, 16, 1,
FaceEngine.ASF_FACE_DETECT |
FaceEngine.ASF_FACE_RECOGNITION);
LogUtils.dTag(TAG,
"initResult: " + result);
if (result ==
ErrorInfo.MERR_ASF_NOT_ACTIVATED) {
Executors.newSingleThreadExecutor().execute(() -> {
int activeResult =
FaceEngine.active(
MainActivity.this, Constants.APP_ID, Constants.SDK_KEY);
runOnUiThread(() ->
{
LogUtils.dTag(TAG,
"activeResult: " + activeResult);
if (activeResult ==
ErrorInfo.MOK) {
int initResult =
faceEngine.init(this, DetectMode.ASF_DETECT_MODE_VIDEO,
DetectFaceOrientPriority.ASF_OP_ALL_OUT, 16, 1,
FaceEngine.ASF_FACE_DETECT | FaceEngine.ASF_FACE_RECOGNITION);
LogUtils.dTag(TAG, "initResult: " + initResult);
if