opencv+ArcFace人脸识别

        前几天逛知乎看到有免费的工具来做人脸识别,觉得很有意思;心血来潮,想自己也搞一个人脸识别;不得不说虹软ArcFace真的是太好用了;对于我这种完全不懂人脸识别算法的人,也可以构建出人脸识别的应用;只需要调用封装好的API就行了。
环境准备:

  • 1.到虹软ArcFace官网下载虹软ArcFacezip格式的压缩文件,解压后将libs文件夹copy到自己的工程下,注意libs文件下有一个:arcsoft-sdk-face-3.0.0.0.jar,添加工程对jar的路径依赖;
  • 2.maven下载opencv;
    <!--opencv-->
    <dependency>
        <groupId>org.bytedeco</groupId>
        <artifactId>javacv-platform</artifactId>
        <version>1.4.1</version>
    </dependency>
 
    <dependency>
        <groupId>org.bytedeco.javacpp-presets</groupId>
        <artifactId>opencv-platform</artifactId>
        <version>3.4.1-1.4.1</version>
    </dependency>

    <!-- jna:调用windows系统的API~-->
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>5.8.0</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna-platform</artifactId>
        <version>5.8.0</version>
    </dependency>

项目的结构:
在这里插入图片描述

arcFace

从官方下载的zip文件节后,samplecode文件夹下FaceEngineTest.java是官方给出的示例代码;下面是人脸特征对比部分的代码:

        //从官网获取
        String appId = "";
        String sdkKey = "";
        //加载dll文件,就是最开始准备的libs下面的dll文件路径;      
        FaceEngine faceEngine = new FaceEngine("E:/Project/2021/face-learning/libs/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 = ImageFactory.getRGBData(new File("C:\\Users\\Pictures\\b0488b9ed27271eab692bd0097fe67ce.jpeg"));
        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
        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("特征值1大小:" + faceFeature.getFeatureData().length);
      

        //人脸检测2
        ImageInfo imageInfo2 = ImageFactory.getRGBData(new File("C:\\Users\\Pictures\\WIN_20210628_13_25_19_Pro.jpg"));
        List<FaceInfo> faceInfoList2 = new ArrayList<FaceInfo>();
        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("特征值2大小:" + faceFeature2.getFeatureData().length);
      
        //特征比对
        FaceSimilar faceSimilar = new FaceSimilar();
        errorCode = faceEngine.compareFaceFeature(faceFeature, faceFeature2, faceSimilar);

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


上面这段代码流程:

  • 1.FaceEngine引擎 对象创建(加载dll文件)
  • 2.激活引擎
  • 3.引擎配置,功能配置
  • 4.初始化引擎
  • 5.分别做2张图片的:人脸检测:imageInfo(人脸信息),特征提取:faceFeatur(人脸特征)
  • 6.对比2张图片的人脸特征,得出相似度FaceSimilar

opencv

用opencv调用摄像头,获取实时的人脸信息;


	OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
	Java2DFrameConverter converter =  new Java2DFrameConverter();
	grabber.start();   //开始获取摄像头数据
	Frame frame = grabber.grab();//获取此刻的图像数据
	BufferedImage bufferedImage = converter.convert(frame);//opencv:用Java2DFrameConverter将Frame转化成BufferedImage 
	ImageInfo imageInfo =ImageFactory.bufferedImage2ImageInfo(bufferedImage);//ArcFace:获取到人脸信息;

opencv_ArcFace

将上面的代码整合一下


public class TestArcFace{
    static  String appId = "";
    static String sdkKey = "";
    static String enginePath ="E:/Project/2021/face-learning/libs/WIN64";
    static OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
    static Java2DFrameConverter converter =  new Java2DFrameConverter();


	public static void main(String[] args) throws Throwable{
        FaceEngine faceEngine = getFaceEngine();//获取FaceEngine
        grabber.start();//开启摄像头
        FaceFeature bossFace = getFaceFeature(faceEngine,getImageInfoFromPicture("")).get(0);//从boss的单人照中获取boss脸部特征
        boolean bossComing=false;
        while(!bossComing){//检测boss是否出现摄像头中;
            List<FaceFeature> captureFaces  = getFaceFeature(faceEngine,getImageInfoFromCamera());//捕获出现在镜头中的人脸特征
            for (FaceFeature captureFace : captureFaces) {//遍历list检测捕获到的人脸特征
                FaceSimilar faceSimilar = getFaceSimilar(faceEngine,captureFace,bossFace);
                 if(samePeople(faceSimilar,0.8f)){//boss出现
                     bossComing=true;
                     break;
                 }
            }
            Thread.sleep(100);//每隔100ms检测一次,检测boss是否出现在镜头中。。
        }
        User32.INSTANCE.LockWorkStation();//锁屏
        grabber.stop();
        faceEngine.unInit();
}




    public static FaceEngine getFaceEngine(){
        FaceEngine faceEngine = new FaceEngine(enginePath);
        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(30);//人脸相对于所在图片的长边的占比,建议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(ErrorInfo.MOK.getValue()!= errorCode){
            throw new RuntimeException("初始化引擎失败。。。errorCode:"+errorCode);
        }
        return faceEngine;
    }
    /*
    获取图片中人脸信息
     */
    public static ImageInfo getImageInfoFromPicture(String picturePath){
        return ImageFactory.getRGBData(new File(picturePath));
    }
    /*
    从摄像头中获取到人脸信息;
     */
    public static ImageInfo getImageInfoFromCamera() throws FrameGrabber.Exception {
        Frame frame = grabber.grab();
        BufferedImage bufferedImage = converter.convert(frame);
        return ImageFactory.bufferedImage2ImageInfo(bufferedImage);
    }

    /*
    获取ImageInfo人脸特征
     */
    public  static List<FaceFeature> getFaceFeature(FaceEngine faceEngine,ImageInfo imageInfo){


        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
        List<FaceFeature> faceFeatures = new ArrayList<>();
        //提取人脸信息
        faceEngine.detectFaces(imageInfo.getImageData(),imageInfo.getWidth(),imageInfo.getHeight(),imageInfo.getImageFormat(),faceInfoList);
        if(!faceInfoList.isEmpty()){
            //提取人脸特征
            for (FaceInfo faceInfo : faceInfoList) {
                FaceFeature faceFeature = new FaceFeature();
                faceEngine.extractFaceFeature(imageInfo.getImageData(),imageInfo.getWidth(),imageInfo.getHeight(),imageInfo.getImageFormat(),faceInfo,faceFeature);
                faceFeatures.add(faceFeature);
            }
        }else{
            System.out.println("faceInfoList is empty");
        }
        return faceFeatures;
    }

    /*
    对比FaceFeature,获取相似度
     */
    public static FaceSimilar getFaceSimilar(FaceEngine faceEngine,FaceFeature captureFaceFeature,FaceFeature target){
        FaceSimilar faceSimilar = new FaceSimilar();
        faceEngine.compareFaceFeature(captureFaceFeature,target,faceSimilar);
        return faceSimilar;
    }


    /*
    判断是否是同一个人,
    score:自定义设置 ;
    当相似度超过score,判定是同一人;
     */
    public static boolean samePeople(FaceSimilar faceSimilar,float score){
        return faceSimilar.getScore()>score?true:false;
    }

}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值