最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

【独家】百度人脸识别_SpringBoot整合离线SDK

来源:博客园


(资料图片)

一、前言

  1. 建议使用低版本 SDK : Baidu_Face_Offline_SDK_Windows_Java_6.1.3
    • 目前已知8.x版本对服务端不兼容,存在运行过程中,第一次调用sdk能够正常执行,第二次时出现JVM异常。
    • SDK不支持多线程,一般都用于设备端,如人脸闸机上的面板机设备。
  2. 自定义库文件路径,与项目分离。
  3. 整合springBoot项目,实现启动初始化SDK,按需调用。

二、SDK 引入并配置

  1. 解压程序,查看对应操作系统的文件夹,将src目录下的文件移动到我们的项目中。请不要修改此目录结构。
  1. 给Face.java类添加注解,实现条件实例化。
@Slf4j@Component@Conditional(FaceSdkEnableCondition.class)public class Face {    // *******以下为人脸sdk api接口*********
  1. 修改Face.java类加载库的方式,以及初始化。
    1. 新增 Environment 类动态获取库路径。
    2. 更换 System.load() 加载库文件。
    3. 使用 @PostConstruct注解,当类对象被创建时,自动完成初始化工作。
    4. 使用 @PreDestroy注解,当类对象被销毁时,自动完成释放内存工作。
// ********* 以下为系统加载库文件及opencv **********    private static String libPath;    public Face(){ }    @Autowired    public Face(Environment env) {        // 初始化libPath        libPath = env.getProperty("face-sdk.libPath",String.class);        // 加载dll文件        System.load(libPath + "BaiduFaceApi.dll");        System.load(libPath + "opencv_java320.dll");    }    Face api = null;    /*  sdk初始化 */    @PostConstruct    public void init() {        log.info("离线SDK开始初始化");        log.info("SDK路径:{}",libPath);        api = new Face();        int res = api.sdkInit(libPath);        if (res != 0) {            log.info("sdk init fail and error = {}\n", res);            return;        }        log.info("离线SDK初始化完成");    }    /*  sdk释放内存 */    @PreDestroy    private void destroy() {        if(api != null){            api.sdkDestroy();        }        log.info("离线SDK销毁");    }
  1. 配置条件启动类相关
package cn.dyina.config;public class FaceSdkEnableCondition implements Condition {    @Override    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {        Environment env = context.getEnvironment();        // 根据face-sdk.enable属性来决定是否创建 Face bean        return "true".equals(env.getProperty("face-sdk.enable"));    }}
  1. 配置路径存放库文件

    face-sdk:  enable: true  # 路径请务必使用双斜杆  libPath: D:\\FaceLib\\  imagesPath: D:\\FaceImages\\
    1. 请将SDK文件的所有.dll文件拷贝到 libPath目录下。
    2. 请将SDK文件下的opencv-jar、models、license文件夹拷贝到libPath目录下。
    3. 请登录 百度智能云 控制中心,注册并获取离线识别SDK序列号,替换license\license.key内的序列号。
  2. 安装maven依赖,以解决打包异常

    1. 修改并在项目终端执行以下的命令,将opencv-jar下的opencv-320.jar依赖安装到maven仓库。
    mvn install:install-file -DgroupId=cn.dyina(jar包的groupId) -DartifactId=opencv-jar(jar包的artifactId) -Dversion=1.0(jar的版本号) -Dpackaging=jar -Dfile=D:\FaceLib\opencv-jar\opencv-320.jar(jar包的具体路径)
    1. 添加maven依赖
        cn.dyina    opencv-jar    1.0

三、项目使用

  1. 在SpringBoot启动类上,添加包扫描。
@SpringBootApplication(scanBasePackages = {"cn.dyina","com.jni"})public class SpringBootBaiDuFaceSdkApplication {    //...}
  1. 编写service、controller。(以下示例代码仅提供参考,请根据自己的业务需求进行编写。)
@Slf4j@Servicepublic class FaceService {    @Value("${face-sdk.imagesPath}")    String imagesPath;    public String registerFace(String fileName, String nickName) {        // 注册人脸图片        String ip_nickName = fileName.replaceFirst("[.][^.]+$", "");        // 获取人脸特征值        Mat mat = Imgcodecs.imread(imagesPath + fileName);        long matAddr = mat.getNativeObjAddr();        // 填充人脸信息 后期将从数据库获取        String userInfo = nickName;        String userId = ip_nickName.replace(".","");        String groupId = "Face";        // 用人脸特征值注册        JSONObject res = JSONObject.parseObject(Face.userAddByMat(matAddr, userId, groupId, userInfo));        log.info("user add result is:{}", res);        return res.getString("msg");    }    public String identifyFace(String fileName) {        // 调用人脸sdkAPI        Face.loadDbFace();        Mat mat1 = Imgcodecs.imread(imagesPath + fileName);        long mat1Addr = mat1.getNativeObjAddr();        int type = 0;        // 和人脸库里面的人脸特征值比较(人脸识别)        JSONObject res = JSONObject.parseObject(Face.identifyWithAllByMat(mat1Addr, type));        log.info("identify res is:{}", res);        if (!res.getString("errno").equals("0")) {            return res.getString("msg");        }        // 获取人脸识别信息        double score = res.getJSONObject("data")                .getJSONArray("result")                .getJSONObject(0)                .getDouble("score");        String userId = res.getJSONObject("data")                .getJSONArray("result")                .getJSONObject(0)                .getString("user_id");        if (score > 80) {            String nickName = userId.split("_")[1];            return nickName;        } else {            log.info("根据图片获取人员信息失败");            return "Match score is low";        }    }}
/** *  人脸识别 页面相关接口 */@Slf4j@RestController@CrossOrigin(origins = "*", maxAge = 3600)public class FaceController {    @Autowired    private FaceService faceService;    @Value("${face-sdk.imagesPath}")    String imagesPath;    /**     * 人脸注册     * @param file     * @param ip     * @param nickName     * @return     * @throws IOException     */    @PostMapping("/faceRegister")    public R faceRegister(@RequestParam("photo") MultipartFile file,                                  @RequestParam("ip") String ip,                                  @RequestParam("nickName") String nickName) throws IOException {        String photo = Base64.getEncoder().encodeToString(file.getBytes());        String fileName = ip + "_" + nickName + ".jpg";        Base64ToImage.saveImage(imagesPath, fileName, photo);        // 人脸注册        String res = faceService.registerFace(fileName, nickName);        if(!res.equals("success")){            return R.error(res,null);        }        return R.success(null);    }    /**     * 检测人脸     * @param photo     * @param ip     * @return     */    @PostMapping("/faceDetection")    public R faceDetection(@RequestParam("photo") String photo, @RequestParam("ip") String ip) {        String fileName = ip +".jpg"; // 临时存储,用于检测        Base64ToImage.saveImage(imagesPath, fileName, photo);        String res = faceService.identifyFace(fileName);        return R.success(res);    }    /**     * 查询用户组人脸     * @param groupId     * @return     */    @GetMapping("/getAllFace")    public R getAllFace(@RequestParam("groupId") String groupId){        log.info("====>> getAllFace");        List userIdList = faceService.getAllFace(groupId);        return R.success(userIdList);    }}

后记

  1. com.jni.face包下,除了Face.java类,其他都是示例程序,可以视情况删除。

  2. models 文件夹里的模型可以按情况删除,详细可以查看文档。

  3. 项目启动后,你的控制台应该会收到SDK初始化的信息。并且你的libPath目录下应该生成db文件夹,人脸数据将存储在这里。(db文件夹将生成在库文件所在目录。删除face.db后,初始化SDK时会自动生成,不需要额外操作。)

  4. 有生产需求的,但设备量不多,可以咸鱼买序列号。(官网最低100个起购)

关键词: