人脸识别能力集成使用(部分免费)


       今天的进度完成了,这会就是一些收尾工作。打开CSDN看看最新的技术新闻,看到了OpenCV-Python实战人脸识别。一直也想涉足下,了解了下OpenCV。打开官网看了下,貌似free的,可以研究下。但是好像工程有点大,这一时半会出不了效果,侧面了解了有做封装的公司了。下面就介绍下,在测试项目上集成玩下,实际上人脸识别这块公司业务中也是需求偏高的智能设备之一。

一、集成准备

官网:https://ai.arcsoft.com.cn/
       这个个人开发就可以免费提供一些的人脸相关能力的,基本上小业务量、轻量还是可以使用的。准备姿势:

  1. 注册账号
  2. 个人实名认证
  3. 下载demo(最新免费版是3.0的)
    在这里插入图片描述
    PS:
    1、支持的平台window、Linux、IOS、Android
    2、支持的语言JAVA、C++、ObjectC

二、demo文件

       这个因为不是开源的,maven上还没有jar。所以需要自行设置,设置如下:
文件放置目录:
在这里插入图片描述
        如果同时要支持linux,也是可以下载Linux64放到这里的,后面可以通过jvm读取服务器系统信息,走不同的驱动加载引擎。
pom.xml引入依赖

<!-- 虹软人脸识别 -->
<dependency>
    <groupId>com.arcsoft.face</groupId>
    <artifactId>arcsoft-sdk-face</artifactId>
    <version>3.0.0.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/libs/arcsoft-sdk-face-3.0.0.0.jar</systemPath>
</dependency>

三、使用姿势

      虹软封装的引擎思路很清晰:
         1、读取授权信息
         2、读取驱动文件
         3、加载激活引擎
         4、对引擎设置功能配置
         5、使用功能
       后面大家看测试代码好好捋捋是不是这么个思路,我反正很细化这种思路,清晰明了,就好像要干啥先穿啥衣服,然后再干。测试代码是demo稍微改下,说实话demo演示了免费的使用基本姿势,高级姿势有pdf帮助文档和官网,还是很香的。

package face.arcsoft;

import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import com.alibaba.fastjson.JSON;
import com.arcsoft.face.*;
import com.arcsoft.face.enums.*;
import com.arcsoft.face.toolkit.ImageInfo;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.arcsoft.face.toolkit.ImageInfoEx;

import static com.arcsoft.face.toolkit.ImageFactory.getGrayData;
import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;


public class FaceEngineTest {

    public static void main(String[] args) {
        System.out.println("------人脸比对测试------");

        //使用HuTool提供的工具类读取系统信息也很香啊
        OsInfo osInfo = SystemUtil.getOsInfo();
        System.out.println("--系统信息:" + JSON.toJSONString(osInfo));
        System.out.println("--系统操作系统:" + osInfo.getName() + "版本:" + osInfo.getVersion());
        String facePathA = "C:\Users\zhengwen\Desktop\test\face\old.jpg";
        System.out.println("A测试图片路径:" + facePathA);
        String facePathB = "C:\Users\zhengwen\Desktop\test\face\20211112.jpg";
        //String facePathB = "C:\Users\zhengwen\Desktop\test\face\ldh.jpg";

        System.out.println("B测试图片路径:" + facePathB);

        String irPath = "C:\Users\zhengwen\Desktop\test\face\gg.jpg";
        System.out.println("IR测试图片路径:" + irPath);

        //从官网获取(这里开始可以根据操作系统用不同的id、key、驱动加载引擎)
        String appId = "6mBZvzxhvmRxhHPcFkphS2BsLrsm8Xcm9M6Sc2wLXKiM";
        String sdkKey = "FVQyCohAYFeN6rkA9HtVr27My2qWwrVe5WpMu1MEkTsW";

        String path = System.getProperty("user.dir");

        FaceEngine faceEngine = new FaceEngine(path + File.separator + "libs" + File.separator + "WIN64");
        //激活引擎
        int errorCode = faceEngine.activeOnline(appId, sdkKey);

        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            System.out.println("引擎激活失败");
        }


        ActiveFileInfo activeFileInfo = new ActiveFileInfo();
        errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            System.out.println("获取激活文件信息失败");
        }

        //引擎配置
        EngineConfiguration engineConfiguration = new EngineConfiguration();
        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
        engineConfiguration.setDetectFaceMaxNum(10);
        engineConfiguration.setDetectFaceScaleVal(16);
        //功能配置
        FunctionConfiguration functionConfiguration = new FunctionConfiguration();
        functionConfiguration.setSupportAge(true);
        functionConfiguration.setSupportFace3dAngle(true);
        functionConfiguration.setSupportFaceDetect(true);
        functionConfiguration.setSupportFaceRecognition(true);
        functionConfiguration.setSupportGender(true);
        functionConfiguration.setSupportLiveness(true);
        functionConfiguration.setSupportIRLiveness(true);
        engineConfiguration.setFunctionConfiguration(functionConfiguration);


        //初始化引擎
        errorCode = faceEngine.init(engineConfiguration);

        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("初始化引擎失败");
        }


        //人脸检测
        ImageInfo imageInfo = getRGBData(new File(facePathA));
        List<FaceInfo> faceInfoList = new ArrayList<>();
        errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("A人脸检测失败");
        }

        //特征提取
        FaceFeature faceFeature = new FaceFeature();
        errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
        //System.out.println("特征值大小:" + faceFeature.getFeatureData().length);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("A人脸特征提取失败");
        }

        //人脸检测2
        ImageInfo imageInfo2 = getRGBData(new File(facePathB));
        List<FaceInfo> faceInfoList2 = new ArrayList<>();
        errorCode = faceEngine.detectFaces(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(), imageInfo.getImageFormat(), faceInfoList2);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("B人脸检测失败");
        }

        //特征提取2
        FaceFeature faceFeature2 = new FaceFeature();
        errorCode = faceEngine.extractFaceFeature(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(), imageInfo.getImageFormat(), faceInfoList2.get(0), faceFeature2);
        //System.out.println("特征值大小:" + faceFeature.getFeatureData().length);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("B人脸特征提取失败");
        }

        //特征比对
        FaceFeature targetFaceFeature = new FaceFeature();
        targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
        FaceFeature sourceFaceFeature = new FaceFeature();
        sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());
        FaceSimilar faceSimilar = new FaceSimilar();

        errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("AB人脸特征比对失败");
        }

        System.out.println("AB相似度:" + faceSimilar.getScore());

        //设置活体测试
        errorCode = faceEngine.setLivenessParam(0.5f, 0.7f);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("设置活体测试失败");
        }

        //A人脸属性检测
        FunctionConfiguration configuration = new FunctionConfiguration();
        configuration.setSupportAge(true);
        configuration.setSupportFace3dAngle(true);
        configuration.setSupportGender(true);
        configuration.setSupportLiveness(true);
        errorCode = faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList, configuration);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("A人脸属性检测失败");
        }

        //性别检测
        List<GenderInfo> genderInfoList = new ArrayList<>();
        errorCode = faceEngine.getGender(genderInfoList);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("性别检测失败");
        }
        System.out.println("(0男1女)性别:" + genderInfoList.get(0).getGender());

        //A年龄检测
        List<AgeInfo> ageInfoList = new ArrayList<>();
        errorCode = faceEngine.getAge(ageInfoList);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("年龄检测失败");
        }
        System.out.println("A年龄:" + ageInfoList.get(0).getAge());

        //B人脸属性检测
        FunctionConfiguration configurationB = new FunctionConfiguration();
        configurationB.setSupportAge(true);
        configurationB.setSupportFace3dAngle(true);
        configurationB.setSupportGender(true);
        configurationB.setSupportLiveness(true);
        errorCode = faceEngine.process(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(), imageInfo2.getImageFormat(), faceInfoList2, configurationB);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("A人脸属性检测失败");
        }
        //A年龄检测
        List<AgeInfo> ageInfoList2 = new ArrayList<>();
        errorCode = faceEngine.getAge(ageInfoList2);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("年龄检测失败");
        }
        System.out.println("B年龄:" + ageInfoList2.get(0).getAge());


        //3D信息检测
        List<Face3DAngle> face3DAngleList = new ArrayList<>();
        errorCode = faceEngine.getFace3DAngle(face3DAngleList);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("3D信息检测失败");
        }
        System.out.println("3D角度:" + face3DAngleList.get(0).getPitch() + "," + face3DAngleList.get(0).getRoll() + "," + face3DAngleList.get(0).getYaw());

        //活体检测
        List<LivenessInfo> livenessInfoList = new ArrayList<>();
        errorCode = faceEngine.getLiveness(livenessInfoList);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("活体检测失败");
        }
        System.out.println("活体:" + livenessInfoList.get(0).getLiveness());


        //IR属性处理
        ImageInfo imageInfoGray = getGrayData(new File(irPath));
        List<FaceInfo> faceInfoListGray = new ArrayList<>();
        errorCode = faceEngine.detectFaces(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("IR属性处理失败");
        }

        FunctionConfiguration configuration2 = new FunctionConfiguration();
        configuration2.setSupportIRLiveness(true);
        errorCode = faceEngine.processIr(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray, configuration2);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("IR属性处理设置失败");
        }
        //IR活体检测
        List<IrLivenessInfo> irLivenessInfo = new ArrayList<>();
        errorCode = faceEngine.getLivenessIr(irLivenessInfo);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("IR活体检测失败");
        }
        System.out.println("IR活体:" + irLivenessInfo.get(0).getLiveness());

        ImageInfoEx imageInfoEx = new ImageInfoEx();
        imageInfoEx.setHeight(imageInfo.getHeight());
        imageInfoEx.setWidth(imageInfo.getWidth());
        imageInfoEx.setImageFormat(imageInfo.getImageFormat());
        imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()});
        imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3});
        List<FaceInfo> faceInfoList1 = new ArrayList<>();
        errorCode = faceEngine.detectFaces(imageInfoEx, DetectModel.ASF_DETECT_MODEL_RGB, faceInfoList1);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("图片扩展信息读取失败");
        }

        FunctionConfiguration fun = new FunctionConfiguration();
        fun.setSupportAge(true);
        errorCode = faceEngine.process(imageInfoEx, faceInfoList1, functionConfiguration);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("图片IR属性处理合成失败");
        }
        List<AgeInfo> ageInfoList1 = new ArrayList<>();
        int age = faceEngine.getAge(ageInfoList1);
        //System.out.println("年龄:" + ageInfoList1.get(0).getAge());
        System.out.println("年龄:" + age);

        FaceFeature feature = new FaceFeature();
        errorCode = faceEngine.extractFaceFeature(imageInfoEx, faceInfoList1.get(0), feature);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("图片IR提取人脸特征失败");
        }

        //引擎卸载
        errorCode = faceEngine.unInit();
        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("引擎卸载失败");
        }

    }
}

四、效果

       这里我找了我以前、现在、偶像的一些照片放在一个目录下,方便测试。
在这里插入图片描述
      岁月是把杀猪刀啊,你看看这些年再我脸上雕刻的…
      如果可以回去,你想回到什么时候呢?
      怀恋啊我们的青春啊…

五、控制台测试输出

2021.1.3libidea_rt.jar" face.arcsoft.FaceEngineTest
Connected to the target VM, address: '127.0.0.1:49905', transport: 'socket'
------人脸比对测试------
--系统信息:{"aix":false,"arch":"amd64","fileSeparator":"\","hpUx":false,"irix":false,"lineSeparator":"rn","linux":false,"mac":false,"macOsX":false,"name":"Windows 10","os2":false,"pathSeparator":";","solaris":false,"sunOS":false,"version":"10.0","windows":true,"windows10":true,"windows2000":false,"windows7":false,"windows8":false,"windows8_1":false,"windows95":false,"windows98":false,"windowsME":false,"windowsNT":false,"windowsXP":false}
--系统操作系统:Windows 10版本:10.0
A测试图片路径:C:UserszhengwenDesktoptestfaceold.jpg
B测试图片路径:C:UserszhengwenDesktoptestface20211112.jpg
IR测试图片路径:C:UserszhengwenDesktoptestfacegg.jpg
AB相似度:0.86731297
(01)性别:0
A年龄:24
B年龄:36
3D角度:1.6797562,-0.6365518,-0.97046876
活体:1
IR活体:0
图片IR属性处理合成失败
年龄:0
Disconnected from the target VM, address: '127.0.0.1:49905', transport: 'socket'

Process finished with exit code 0

       老实说,我看到这个根据照片计算出的年龄还是很伤心的,因为本尊现在根本还没到36,还差好多年呢。哎
       打印出来的都有中文意思了,我也不解释了,看看相似度,还是很高的,我测了跟偶像华仔的相似度不到10%。
在这里插入图片描述

六、总结

       首先要说这个还是很不错的,底层也看了下jar里面,也是基于openCV做的。算法、训练估计是自己公司做的,看来还是很有必要好好看看OpenCV,后面有空再基于这个做下分享。
       然后,简单总结下:
1、免费的也不错(基本功能都有,连1:N搜索视频流都可以,个人认证就100台终端可以激活使用)
2、需要联网(私有化部署没有网络的凉凉)
3、官方介绍的响应速度还可以
4、官方给的PDF写的很清楚规范(赞)
5、不需要再购买设备、部署
       最后,我们目前有场景是用的koala做人脸比对。用上这个我不禁想到我们的通行闸机、摄像头人脸识别、摄像头人脸追踪等等似乎都可以用这个解决。其实我们也有做这块的规划的,就是人才少,留不住。
       更多有趣的功能大家可以注册个人版使用,希望可以帮到大家,启迪到大家,加油技术人。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>