前言

java实现人脸识别,数据存储在mongo中(只是个Demo,仅用于学习)

1:没有手写算法(那是大佬干的事),调用虹软的SDK
2:没有使用mongo GridFS存储照片,只是存储了照片的特征

一、获取SDK

1:登录虹软官网,选择 x64 位的java版本SDK
2:记录下APP_ID,SDK_KEY

下载的.zip包里有javaDemo,.jar,.dll。
idea里面让项目依赖jar包:file -> project structure -> modules -> 选择模块 -> dependencies -> 右边+,选择jar包
看官网介绍就知道怎么使用。

二、实现人脸识别

1.对象

@Data
public class FaceDemo {
    /**
     * 主键id
     **/
    @Id
    private Long id;
    /**
     * 特征
     **/
    private byte[] faceFeature;
    /**
     * 姓名
     **/
    private String name;
    /**
     * 相似度 0-100
     **/
    private Integer similarValue;
}

2.接口类

public interface FaceDemoRepository extends MongoRepository<FaceDemo,Long> {
}

3.配置类

@Slf4j
@Component
public class FaceEngineInit implements CommandLineRunner {

    @Value("${faceDemo.hongRuan.appId}")
    private String appId;
    @Value("${faceDemo.hongRuan.appKey}")
    private String appKey;
    @Value("${faceDemo.hongRuan.dllPath}")
    private String dllPath;

    public FaceEngine faceEngine;

    @Override
    public void run(String... args) throws Exception {
        log.debug("初始化人脸识别引擎...开始");
        faceEngine = new FaceEngine(System.getProperty("user.dir") + dllPath);
        //激活引擎
        int errorCode = faceEngine.activeOnline(appId, appKey);
        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("初始化引擎失败");
        }
        log.debug("初始化人脸识别引擎...结束");
    }

}

4.控制类

import com.arcsoft.face.*;
import com.arcsoft.face.toolkit.ImageInfo;
import com.google.common.collect.Lists;
import com.tao.faceDemo.config.FaceEngineInit;
import com.tao.faceDemo.entity.FaceDemo;
import com.tao.faceDemo.service.FaceDemoRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

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

@Slf4j
@RestController
@RequestMapping(value = "faceDemo")
public class FaceController {
    @Value("${faceDemo.hongRuan.similarValueTemplate}")
    private Integer similarValueTemplate;
    @Value("${faceDemo.hongRuan.tempDir}")
    private String tempDir;

    @Autowired
    private FaceDemoRepository faceDemoRepository;
    @Autowired
    private FaceEngineInit faceConfig;

    @RequestMapping(value = "faceAdd", method = RequestMethod.POST)
    public Long faceAdd(@RequestParam("file") MultipartFile file, @RequestParam("name") String name) throws IOException {
        //根据照片获取特征
        FaceFeature faceFeature = this.getFaceFeature(file);
        //将特诊数据存入mongo
        FaceDemo faceDemo = new FaceDemo();
        faceDemo.setId(System.currentTimeMillis());
        faceDemo.setFaceFeature(faceFeature.getFeatureData());
        faceDemo.setName(name);
        //插入mongodb
        faceDemoRepository.insert(faceDemo);
        return faceDemo.getId();
    }

    @RequestMapping(value = "faceCompare", method = RequestMethod.POST)
    public FaceDemo faceCompare(@RequestParam("file") MultipartFile file) throws IOException {
        System.out.println("similarValueTemplate = " + similarValueTemplate);
        System.out.println("tempDir = " + tempDir);

        //根据照片获取特征
        FaceFeature faceFeature = this.getFaceFeature(file);
        //查询库里所有特征  这里没有考虑到 百万级数据的问题
        //todo 百万计数据时,查询使用分页,比较特征使用线程池submit
        List<FaceDemo> faceDemoList = faceDemoRepository.findAll();
        //遍历库里数据,获得大于相似度的值
        List<FaceDemo> resultFaceInfoList = Lists.newLinkedList();
        FaceEngine faceEngine = faceConfig.faceEngine;
        for (FaceDemo faceDemo : faceDemoList) {
            FaceFeature sourceFaceFeature = new FaceFeature();
            sourceFaceFeature.setFeatureData(faceDemo.getFaceFeature());
            FaceSimilar faceSimilar = new FaceSimilar();
            faceEngine.compareFaceFeature(faceFeature, sourceFaceFeature, faceSimilar);
            //获取相似值
            Integer similarValue = plusHundred(faceSimilar.getScore());
            //相似值大于配置预期,加入到识别到人脸的列表
            if (similarValue > similarValueTemplate) {
                FaceDemo info = new FaceDemo();
                info.setName(faceDemo.getName());
                info.setSimilarValue(similarValue);
                resultFaceInfoList.add(info);
            }
        }
        if (CollectionUtils.isEmpty(resultFaceInfoList)) {
            return null;
        }
        //从大到小排序
        resultFaceInfoList.sort((h1, h2) -> h2.getSimilarValue().compareTo(h1.getSimilarValue()));
        return resultFaceInfoList.get(0);
    }

    private int plusHundred(Float value) {
        BigDecimal target = new BigDecimal(value);
        BigDecimal hundred = new BigDecimal(100f);
        return target.multiply(hundred).intValue();
    }

    public FaceFeature getFaceFeature(MultipartFile file) throws IOException {
        File temp = new File(System.getProperty("user.dir") + tempDir + file.getOriginalFilename());
        file.transferTo(temp);
        //人脸检测
        ImageInfo imageInfo = getRGBData(temp);
        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
        FaceEngine faceEngine = faceConfig.faceEngine;
        int errorCode;
        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);
        return faceFeature;
    }
}

代码如下(示例):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

5.人脸识别的配置参数

## 人脸识别参数
faceDemo:
  hongRuan: 
    appId: XXXXXXXXXX
    appKey: XXXXXXXXXX
    similarValueTemplate: 85
    tempDir: /faceAdd/
    dllPath: /dllPath

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


最后说明

1:faceAdd文件夹的作用:MultipartFile转File使用的临时文件夹,也可以使用其他方式转为File,如:流
2:这只是个demo,没有考虑到大数据量的情况,但相信几百几千的人脸对比还是能支持的。

在这里插入图片描述
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐