百度人脸识别_SpringBoot整合离线SDK

打印 上一主题 下一主题

主题 926|帖子 926|积分 2778

一、前言


  • 建议使用低版本 SDK : Baidu_Face_Offline_SDK_Windows_Java_6.1.3

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


  • 解压程序,查看对应操作系统的文件夹,将src目录下的文件移动到我们的项目中。请不要修改此目录结构。

  • 给Face.java类添加注解,实现条件实例化。
  1. @Slf4j
  2. @Component
  3. @Conditional(FaceSdkEnableCondition.class)
  4. public class Face {
  5.     // *******以下为人脸sdk api接口*********
复制代码

  • 修改Face.java类加载库的方式,以及初始化。

    • 新增 Environment 类动态获取库路径。
    • 更换 System.load() 加载库文件。
    • 使用 @PostConstruct 注解,当类对象被创建时,自动完成初始化工作。
    • 使用 @PreDestroy 注解,当类对象被销毁时,自动完成释放内存工作。
      
  1. // ********* 以下为系统加载库文件及opencv **********
  2.     private static String libPath;
  3.     public Face(){ }
  4.     @Autowired
  5.     public Face(Environment env) {
  6.         // 初始化libPath
  7.         libPath = env.getProperty("face-sdk.libPath",String.class);
  8.         // 加载dll文件
  9.         System.load(libPath + "BaiduFaceApi.dll");
  10.         System.load(libPath + "opencv_java320.dll");
  11.     }
  12.     Face api = null;
  13.     /*  sdk初始化 */
  14.     @PostConstruct
  15.     public void init() {
  16.         log.info("离线SDK开始初始化");
  17.         log.info("SDK路径:{}",libPath);
  18.         api = new Face();
  19.         int res = api.sdkInit(libPath);
  20.         if (res != 0) {
  21.             log.info("sdk init fail and error = {}\n", res);
  22.             return;
  23.         }
  24.         log.info("离线SDK初始化完成");
  25.     }
  26.     /*  sdk释放内存 */
  27.     @PreDestroy
  28.     private void destroy() {
  29.         if(api != null){
  30.             api.sdkDestroy();
  31.         }
  32.         log.info("离线SDK销毁");
  33.     }
复制代码

  • 配置条件启动类相关
  1. package cn.dyina.config;
  2. public class FaceSdkEnableCondition implements Condition {
  3.     @Override
  4.     public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  5.         Environment env = context.getEnvironment();
  6.         // 根据face-sdk.enable属性来决定是否创建 Face bean
  7.         return "true".equals(env.getProperty("face-sdk.enable"));
  8.     }
  9. }
复制代码

  • 配置路径存放库文件
    1. face-sdk:
    2.   enable: true
    3.   # 路径请务必使用双斜杆
    4.   libPath: D:\\FaceLib\\
    5.   imagesPath: D:\\FaceImages\\
    复制代码

    • 请将SDK文件的所有.dll文件拷贝到 libPath 目录下。
    • 请将SDK文件下的opencv-jar、models、license文件夹拷贝到libPath 目录下。
    • 请登录 百度智能云 控制中心,注册并获取离线识别SDK序列号,替换license\license.key内的序列号。
      
  • 安装maven依赖,以解决打包异常


    • 修改并在项目终端执行以下的命令,将opencv-jar下的opencv-320.jar依赖安装到maven仓库。
    1. 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包的具体路径)
    复制代码

    • 添加maven依赖
    1. <dependency>
    2.     <groupId>cn.dyina</groupId>
    3.     <artifactId>opencv-jar</artifactId>
    4.     <version>1.0</version>
    5. </dependency>
    复制代码

三、项目使用


  • 在SpringBoot启动类上,添加包扫描。
  1. @SpringBootApplication(scanBasePackages = {"cn.dyina","com.jni"})
  2. public class SpringBootBaiDuFaceSdkApplication {
  3.     //...
  4. }
复制代码

  • 编写service、controller。(以下示例代码仅提供参考,请根据自己的业务需求进行编写。)
  1. @Slf4j
  2. @Service
  3. public class FaceService {
  4.     @Value("${face-sdk.imagesPath}")
  5.     String imagesPath;
  6.     public String registerFace(String fileName, String nickName) {
  7.         // 注册人脸图片
  8.         String ip_nickName = fileName.replaceFirst("[.][^.]+$", "");
  9.         // 获取人脸特征值
  10.         Mat mat = Imgcodecs.imread(imagesPath + fileName);
  11.         long matAddr = mat.getNativeObjAddr();
  12.         // 填充人脸信息 后期将从数据库获取
  13.         String userInfo = nickName;
  14.         String userId = ip_nickName.replace(".","");
  15.         String groupId = "Face";
  16.         // 用人脸特征值注册
  17.         JSONObject res = JSONObject.parseObject(Face.userAddByMat(matAddr, userId, groupId, userInfo));
  18.         log.info("user add result is:{}", res);
  19.         return res.getString("msg");
  20.     }
  21.     public String identifyFace(String fileName) {
  22.         // 调用人脸sdkAPI
  23.         Face.loadDbFace();
  24.         Mat mat1 = Imgcodecs.imread(imagesPath + fileName);
  25.         long mat1Addr = mat1.getNativeObjAddr();
  26.         int type = 0;
  27.         // 和人脸库里面的人脸特征值比较(人脸识别)
  28.         JSONObject res = JSONObject.parseObject(Face.identifyWithAllByMat(mat1Addr, type));
  29.         log.info("identify res is:{}", res);
  30.         if (!res.getString("errno").equals("0")) {
  31.             return res.getString("msg");
  32.         }
  33.         // 获取人脸识别信息
  34.         double score = res.getJSONObject("data")
  35.                 .getJSONArray("result")
  36.                 .getJSONObject(0)
  37.                 .getDouble("score");
  38.         String userId = res.getJSONObject("data")
  39.                 .getJSONArray("result")
  40.                 .getJSONObject(0)
  41.                 .getString("user_id");
  42.         if (score > 80) {
  43.             String nickName = userId.split("_")[1];
  44.             return nickName;
  45.         } else {
  46.             log.info("根据图片获取人员信息失败");
  47.             return "Match score is low";
  48.         }
  49.     }
  50. }
复制代码
  1. /**
  2. *  人脸识别 页面相关接口
  3. */
  4. @Slf4j
  5. @RestController
  6. @CrossOrigin(origins = "*", maxAge = 3600)
  7. public class FaceController {
  8.     @Autowired
  9.     private FaceService faceService;
  10.     @Value("${face-sdk.imagesPath}")
  11.     String imagesPath;
  12.     /**
  13.      * 人脸注册
  14.      * @param file
  15.      * @param ip
  16.      * @param nickName
  17.      * @return
  18.      * @throws IOException
  19.      */
  20.     @PostMapping("/faceRegister")
  21.     public R<String> faceRegister(@RequestParam("photo") MultipartFile file,
  22.                                   @RequestParam("ip") String ip,
  23.                                   @RequestParam("nickName") String nickName) throws IOException {
  24.         String photo = Base64.getEncoder().encodeToString(file.getBytes());
  25.         String fileName = ip + "_" + nickName + ".jpg";
  26.         Base64ToImage.saveImage(imagesPath, fileName, photo);
  27.         // 人脸注册
  28.         String res = faceService.registerFace(fileName, nickName);
  29.         if(!res.equals("success")){
  30.             return R.error(res,null);
  31.         }
  32.         return R.success(null);
  33.     }
  34.     /**
  35.      * 检测人脸
  36.      * @param photo
  37.      * @param ip
  38.      * @return
  39.      */
  40.     @PostMapping("/faceDetection")
  41.     public R<String> faceDetection(@RequestParam("photo") String photo, @RequestParam("ip") String ip) {
  42.         String fileName = ip +".jpg"; // 临时存储,用于检测
  43.         Base64ToImage.saveImage(imagesPath, fileName, photo);
  44.         String res = faceService.identifyFace(fileName);
  45.         return R.success(res);
  46.     }
  47.     /**
  48.      * 查询用户组人脸
  49.      * @param groupId
  50.      * @return
  51.      */
  52.     @GetMapping("/getAllFace")
  53.     public R<List> getAllFace(@RequestParam("groupId") String groupId){
  54.         log.info("====>> getAllFace");
  55.         List<String> userIdList = faceService.getAllFace(groupId);
  56.         return R.success(userIdList);
  57.     }
  58. }
复制代码
后记


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

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

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

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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

民工心事

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表