人脸识别的核心业务流程介绍

触控感测

201人已加入

描述

1、通用流程概述

根据实际应用场景以及硬件配置,活体检测和特征提取可选择是否采用并行的方式。

人脸识别

如上图所示,人脸识别的核心业务流程可以分为以下四个步骤:

a)人脸检测:采集视频帧或静态图,传入算法进行检测,输出人脸数据,用于后续的检测。 b)活体检测:在人脸识别过程中判断操作用户是否为真人,有效防御照片、视频、纸张等不同类型的作弊攻击,提高业务安全性,可根据应用场景选择是否接入; c)特征提取:对待比对的图像进行特征提取、人脸库的预提取,用于之后的比对; d)人脸识别:1:1比对主要是判断「你是你」,用于核实身份的真实性;1:N搜索主要识别「你是谁」,用于明确身份的具体所属。

虹软产品:

ArcFace 离线SDK,包含人脸检测、性别检测、年龄检测、人脸识别、图像质量检测、RGB活体检测、IR活体检测等能力,初次使用时需联网激活,激活后即可在本地无网络环境下工作,可根据具体的业务需求结合人脸识别SDK灵活地进行应用层开发。

人脸识别

人脸识别

2、ArcFace接入集成及示例

2.1 SDK的获取

访问ArcSoft AI开放平台门户:https://ai.arcsoft.com.cn,注册开发者账号并登录。

SDK下载

创建对应的应用,并选择需要下载的SDK、对应平台以及版本,确认后即可下载SDK。

人脸识别

查看APP_ID、SDK_KEY ,点击下载图标获取SDK开发包。

人脸识别

2.2 SDK包结构

|---doc
|   |---ARCSOFT_ARC_FACE_JAVA_DEVELOPER'S_GUIDE.pdf   开发说明文档
|---lib
|---|---Win32/x64
|   |---|---libarcsoft_face.dll             算法库
|   |---|---libarcsoft_face_engine.dll            引擎库 
|   |---|---libarcsoft_face_engine_jni.dll            引擎库
|   |---arcsoft-sdk-face-3.0.0.0.jar            java依赖库
|---samplecode
|   |---FaceEngineTest.java                             示例代码
|---releasenotes.txt                                    说明文件

2.3 指标

算法检测指标受硬件配置、图像数据质量、测试方法等因素影响,以下实验数据仅供参考,具体数据以实际应用场景测试结果为准。

2.3.1 算法性能

硬件信息

处理器:Intel Core i5-8500 3.0GHz

安装内存(RAM):16.0GB(15.9GB可用)

系统类型:win10 64位操作系统

分辨率:1280 x 720

不同人脸库条件下人脸比对+RGB活体检测全流程体感耗时

人脸库 性能(ms)
1000 < 200
5000 < 300
10000 < 600

2.3.2 阈值推荐

活体取值范围为[0~1],推荐阈值如下,高于此阈值的即可判断为活体。

RGB 活体:0.5

IR 活体:0.7

人脸比对取值范围为[0~1],推荐阈值如下,高于此阈值的即可判断为同一人。

用于生活照之间的特征比对,推荐阈值0.80

用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82

2.3.3 图像质量要求

建议待检测的图像人脸角度上、下、左、右转向小于30度;

图片中人脸尺寸不小于50 x 50像素;

图片大小小于10MB;

图像清晰;

2.4 在项目中引入 SDK 包

        
            com.arcsoft.face 
            arcsoft-sdk-face 
            3.0.0.0 
            system 
            ${project.basedir}/lib/arcsoft-sdk-face-3.0.0.0.jar
         

2.4.1 简要集成示例

package com.arcsoft;


import com.arcsoft.face.*;
import com.arcsoft.face.enums.ImageFormat;
import javax.imageio.ImageIO;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class FaceEngineTest {

    public static void main(String[] args) {
        new FaceEngineTest().faceEngineTest();
    }


    public void faceEngineTest() {
        String appId = "";
        String sdkKey = "";


        FaceEngine faceEngine = new FaceEngine();
        //激活引擎
        faceEngine.active(appId, sdkKey);
        EngineConfiguration engineConfiguration = EngineConfiguration.builder().functionConfiguration(
                FunctionConfiguration.builder()
                        .supportAge(true)
                        .supportFace3dAngle(true)
                        .supportFaceDetect(true)
                        .supportFaceRecognition(true)
                        .supportGender(true)
                        .supportLiveness(true)
                        .build()).build();
        //初始化引擎
        faceEngine.init(engineConfiguration);


        ImageInfo imageInfo = getRGBData(new File("d:\1.jpg"));
        ImageInfo imageInfo2 = getRGBData(new File("d:\2.jpg"));
        //人脸检测
        List faceInfoList = new ArrayList();
        faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList);
        
        List faceInfoList2 = new ArrayList();
        faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList2);


        //提取人脸特征
        FaceFeature faceFeature = new FaceFeature();
        faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList.get(0), faceFeature);


        FaceFeature faceFeature2 = new FaceFeature();
        faceEngine.extractFaceFeature(imageInfo2.getRgbData(), imageInfo2.getWidth(), imageInfo2.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList2.get(0), faceFeature2);
        //人脸对比
        FaceFeature targetFaceFeature = new FaceFeature();
        targetFaceFeature.setFeatureData(faceFeature.getFeatureData());


        FaceFeature sourceFaceFeature = new FaceFeature();
        sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());


        FaceSimilar faceSimilar = new FaceSimilar();
        faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
        int processResult = faceEngine.process(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList, FunctionConfiguration.builder().supportAge(true).supportFace3dAngle(true).supportGender(true).supportLiveness(true).build());
        //性别提取
        List genderInfoList = new ArrayList();
        int genderCode = faceEngine.getGender(genderInfoList);
        //年龄提取
        List ageInfoList = new ArrayList();
        int ageCode = faceEngine.getAge(ageInfoList);
        //3D信息提取
        List face3DAngleList = new ArrayList();
        int face3dCode = faceEngine.getFace3DAngle(face3DAngleList);
        //活体信息
        List livenessInfoList = new ArrayList();
        int livenessCode = faceEngine.getLiveness(livenessInfoList);
        System.out.println();
    }
    public ImageInfo getRGBData(File file) {
        if (file == null)
            return null;
        ImageInfo imageInfo;
        try {
            //将图片文件加载到内存缓冲区
            BufferedImage image = ImageIO.read(file);
            imageInfo = bufferedImage2ImageInfo(image);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return imageInfo;
    }
    private ImageInfo bufferedImage2ImageInfo(BufferedImage image) {
        ImageInfo imageInfo = new ImageInfo();
        int width = image.getWidth();
        int height = image.getHeight();
        // 使图片居中
        width = width & (~3);
        height = height & (~3);
        imageInfo.setWidth(width);
        imageInfo.setHeight(height);
        //根据原图片信息新建一个图片缓冲区
        BufferedImage resultImage = new BufferedImage(width, height, image.getType());
        //得到原图的rgb像素矩阵
        int[] rgb = image.getRGB(0, 0, width, height, null, 0, width);
        //将像素矩阵 绘制到新的图片缓冲区中
        resultImage.setRGB(0, 0, width, height, rgb, 0, width);
        //进行数据格式化为可用数据
        BufferedImage dstImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        if (resultImage.getType() != BufferedImage.TYPE_3BYTE_BGR) {
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
            ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints());
            colorConvertOp.filter(resultImage, dstImage);
        } else {
            dstImage = resultImage;
        }
        //获取rgb数据
        imageInfo.setRgbData(((DataBufferByte) (dstImage.getRaster().getDataBuffer())).getData());
        return imageInfo;
    }


    class ImageInfo {
        public byte[] rgbData;
        public int width;
        public int height;
        public byte[] getRgbData() {
            return rgbData;
        }
        public void setRgbData(byte[] rgbData) {
            this.rgbData = rgbData;
        }
        public int getWidth() {
            return width;
        }
        public void setWidth(int width) {
            this.width = width;
        }
        public int getHeight() {
            return height;
        }
        public void setHeight(int height) {
            this.height = height;
        }
    }
}

参考文献:https://ai.arcsoft.com.cn/manual/docs

编辑:黄飞

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分