栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

海康威视+虹软人脸识别

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

海康威视+虹软人脸识别

虹软人脸识别 简介

最近公司项目新需求需要做视频监控+陌生人告警,产品经理和项目经理商量了一周,敲定试用海康威视摄像头+虹软人脸识别进行开发。

刚刚接手需求的时候,都不知道这两个大神是啥东西,百度了一上午,了解了一下两家公司和自己需要的一些技术文档。

首先,这篇文章我们先讲讲虹软人脸识别吧。

虹软科技股份有限公司提供计算机视觉行业算法服务及解决方案,致力于视觉技术的研发和应用,坚持以原创技术为核心驱动力,在全球范围内为智能手机、智能汽车、物联网等智能设备提供一站式视觉解决方案。

准备工作 注册用户

首先,我们要注册一个虹软的账号,申请一个应用。

创建应用

创建应用成功之后,我们需要添加SDK,这里我们已免费版的为例,后续介绍付费版

添加SDK

因为我们的开发环境是windows,服务器环境也是windows,所以这里我选择的是windows平台,这里可以自行进行选择,应该只是库文件的不同。

到这里,我们就能看到 APP_ID 和 SDK_KEY 两个值,后续需要这两个值进行虹软激活

SDK文档

SDK文档:https://ai.arcsoft.com.cn/product/arcface.html

我们下载SDK文档和Java案例之后能看到如下文件

libs目录文件:

  • doc目录里面存放着虹软sdk的接口文档,我们在调用SDK时方便查阅
  • libs目录存放了SDK jar包还有依赖的必要库文件
  • samplecode目录存放了简单的示例代码
添加库文件

对windows操作系统熟悉的朋友,就知道其他程序依赖第三方库文件,需要配置到系统环境变量中。

在Path变量中添加库文件的路径即可

到这里,我们前期工作就差不多完成了

开发环境搭建 引入SDK

首先我们要引入虹软的jar包,因为他是第三方的jar包,没有存放到共有的Maven库中,我们需要手动导入到项目中去。

在Maven中引用

        
        
            com.arcsoft.face
            arcsoft-sdk-face
            3.0.0.0
            system
            ${project.basedir}/src/main/resources/lib/arcsoft-sdk-face-3.0.0.0.jar
        
虹软配置类
@Configuration
public class FaceEngineConfig {

    @Value("${config.freesdk.app-id}")
    private String appId;

    @Value("${config.freesdk.sdk-key}")
    private String sdkKey;

    @Bean
    public FaceEngine getFaceEngineInstance() {
        FaceEngine mFaceEngine = new FaceEngine();
        // 激活引擎
        //在线激活
        int activeCode = mFaceEngine.activeOnline(appId, sdkKey);
        System.out.println("code======>" + activeCode);
        if (activeCode != ErrorInfo.MOK.getValue() && activeCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            System.out.println("引擎激活失败");
        } else {
            System.out.println("引擎激活成功");
        }
        // 引擎配置
        EngineConfiguration engineConfiguration = new EngineConfiguration();
        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);
        // 功能配置,这些配置可以查阅SDK文档,根据自己的需要进行修改
        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);
        // 初始化引擎
        int initCode = mFaceEngine.init(engineConfiguration);

        if (initCode != ErrorInfo.MOK.getValue()) {
            System.out.println("000000=-----初始化引擎失败");
        }
        return mFaceEngine;
    }

}

这里我们使用的是在线激活人脸引擎的方式,这里需要我们把刚刚申请到的appId和sdkKey输入进去

int activeCode = mFaceEngine.activeOnline(appId, sdkKey)

我们也可以查阅SDK文档,这里我们就已激活SDK为例。

到这里,我们就已经把虹软SDK 的bean导入进行了,方便我们后续的操作。

简单使用接口->单个人脸信息

我的需求是拿到海康威视的视频流然后逐帧拿到图片,获取到图片中人脸的信息,这里我们就以获取单个人脸特征信息为例

 
    public byte[] extractFaceFeatureList(FaceInfo f, ImageInfo imageInfo) {
        FaceEngine faceEngine = null;
        try {
            // 获取引擎对象
            faceEngine = imgFaceObjectPool.borrowObject();
            FaceFeature faceFeature = new FaceFeature();
            // 提取人脸特征
            int code = faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(),
                    ImageFormat.CP_PAF_BGR24, f, faceFeature);
            if (code != 0) {
                logger.error("FACE:" + f.getFaceId() + "人脸特征抽取结果不可信" + code);
                //return null;
            }
            return faceFeature.getFeatureData();
        } catch (Exception e) {
            logger.error("人脸特征抽取异常", e);
        } finally {
            if (faceEngine != null) {
                // 释放引擎对象
                imgFaceObjectPool.returnObject(faceEngine);
            }
        }
        return null;
    }

此接口获取到的人脸信息是一个二进制流的形式,我后续是把他存到数据库,项目启动的时候读到缓存中,方便进行人脸比对

faceFeature.getFeatureData()

int code = faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(),ImageFormat.CP_PAF_BGR24, f, faceFeature);
示例代码

在正式开发前也可以用示例代码进行一些简单的测试,看看满不满足你的需求

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) {

        //从官网获取
        String appId = "";
        String sdkKey = "";


        FaceEngine faceEngine = new FaceEngine("D:\arcsoft_lib");
        //激活引擎
        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("d:\aaa.jpg"));
        List faceInfoList = new ArrayList();
        errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
        System.out.println(faceInfoList);

        //特征提取
        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);

        //人脸检测2
        ImageInfo imageInfo2 = getRGBData(new File("d:\ccc.jpg"));
        List faceInfoList2 = new ArrayList();
        errorCode = faceEngine.detectFaces(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(),imageInfo.getImageFormat(), faceInfoList2);
        System.out.println(faceInfoList);

        //特征提取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);

        //特征比对
        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);

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

        //设置活体测试
        errorCode = faceEngine.setLivenessParam(0.5f, 0.7f);
        //人脸属性检测
        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);


        //性别检测
        List genderInfoList = new ArrayList();
        errorCode = faceEngine.getGender(genderInfoList);
        System.out.println("性别:" + genderInfoList.get(0).getGender());

        //年龄检测
        List ageInfoList = new ArrayList();
        errorCode = faceEngine.getAge(ageInfoList);
        System.out.println("年龄:" + ageInfoList.get(0).getAge());

        //3D信息检测
        List face3DAngleList = new ArrayList();
        errorCode = faceEngine.getFace3DAngle(face3DAngleList);
        System.out.println("3D角度:" + face3DAngleList.get(0).getPitch() + "," + face3DAngleList.get(0).getRoll() + "," + face3DAngleList.get(0).getYaw());

        //活体检测
        List livenessInfoList = new ArrayList();
        errorCode = faceEngine.getLiveness(livenessInfoList);
        System.out.println("活体:" + livenessInfoList.get(0).getLiveness());


        //IR属性处理
        ImageInfo imageInfoGray = getGrayData(new File("d:\IR_480p.jpg"));
        List faceInfoListGray = new ArrayList();
        errorCode = faceEngine.detectFaces(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray);

        FunctionConfiguration configuration2 = new FunctionConfiguration();
        configuration2.setSupportIRLiveness(true);
        errorCode = faceEngine.processIr(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray, configuration2);
        //IR活体检测
        List irLivenessInfo = new ArrayList<>();
        errorCode = faceEngine.getLivenessIr(irLivenessInfo);
        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 faceInfoList1 = new ArrayList<>();
        errorCode = faceEngine.detectFaces(imageInfoEx, DetectModel.ASF_DETECT_MODEL_RGB, faceInfoList1);

        FunctionConfiguration fun = new FunctionConfiguration();
        fun.setSupportAge(true);
        errorCode = faceEngine.process(imageInfoEx, faceInfoList1, functionConfiguration);
        List ageInfoList1 = new ArrayList<>();
        int age = faceEngine.getAge(ageInfoList1);
        System.out.println("年龄:" + ageInfoList1.get(0).getAge());

        FaceFeature feature = new FaceFeature();
        errorCode = faceEngine.extractFaceFeature(imageInfoEx, faceInfoList1.get(0), feature);


        //引擎卸载
        errorCode = faceEngine.unInit();

    }
}
碰到的问题

在开发及上线过程中,碰到一些问题进行一些汇总

  1. 添加库文件的问题,在开发中,把代码提交到git上之后,同小组的开发人员拉代码之后因为没有添加库文件的原因报错,这时候添加了库文件没有重启idea,编译器没有及时生效,导致还是会继续报错。解决方案:重启idea
  2. 这里我们使用的是在线激活SDK的方法,查看SDK文档我们知道,在线激活需要服务器能够正常连接公网才行,但是有些项目的生产环境是无法连接公网的,这里我们就需要使用离线增值版的SDK,而虹软官网一般是100个SDK起卖的,一般的公司或者个人开发者是不需要这么大的量的。这里我解决方案就不在文档里说了,有需求的可以私聊我,我可以给你解决方案。

离线增值版激活

你在购买了之后,一般会教你怎么去激活,具体的激活是我买的那个老哥操作的,我说说我怎么配合进行操作吧

  1. 首先他会发一个生产机器激活文件的.exe文件给你,你执行之后就会生成一个文件,虹软后台会需要这个文件生成激活文档。特别注意,这个文件不要在自己的开发环境浪费了
  2. 之后他就会把这个激活文件发给你,在线的SDK和离线增值版的SDK是不一样的,我们需要把jar包进行替换,这里我是直接问那个老哥要的,没去官网找了。(毕竟我花了钱,能不干的事咱就不干),激活文件放到服务器一般不会去看的文件夹里,防止有人手痒给删了。
  3. 之后就是修改激活SDK的方式了,方法就是把激活文件的路径给它就好,如下:
String filePath = "F:\86111149K3RK689A.dat";
int activeCode = mFaceEngine.activeOffline(filePath);
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/530956.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号