一、前言
二、SDK 引入并配置
- 解压程序,查看对应操作系统的文件夹,将src目录下的文件移动到我们的项目中。请不要修改此目录结构。
- @Slf4j
- @Component
- @Conditional(FaceSdkEnableCondition.class)
- public class Face {
- // *******以下为人脸sdk api接口*********
复制代码
- 修改Face.java类加载库的方式,以及初始化。
- 新增 Environment 类动态获取库路径。
- 更换 System.load() 加载库文件。
- 使用 @PostConstruct 注解,当类对象被创建时,自动完成初始化工作。
- 使用 @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销毁");
- }
复制代码- 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"));
- }
- }
复制代码
- 配置路径存放库文件
- face-sdk:
- enable: true
- # 路径请务必使用双斜杆
- libPath: D:\\FaceLib\\
- imagesPath: D:\\FaceImages\\
复制代码
- 请将SDK文件的所有.dll文件拷贝到 libPath 目录下。
- 请将SDK文件下的opencv-jar、models、license文件夹拷贝到libPath 目录下。
- 请登录 百度智能云 控制中心,注册并获取离线识别SDK序列号,替换license\license.key内的序列号。
- 安装maven依赖,以解决打包异常

- 请修改并在项目终端执行以下的命令,将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包的具体路径)
复制代码- <dependency>
- <groupId>cn.dyina</groupId>
- <artifactId>opencv-jar</artifactId>
- <version>1.0</version>
- </dependency>
复制代码
三、项目使用
- @SpringBootApplication(scanBasePackages = {"cn.dyina","com.jni"})
- public class SpringBootBaiDuFaceSdkApplication {
- //...
- }
复制代码
- 编写service、controller。(以下示例代码仅提供参考,请根据自己的业务需求进行编写。)
- @Slf4j
- @Service
- public 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<String> 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<String> 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<List> getAllFace(@RequestParam("groupId") String groupId){
- log.info("====>> getAllFace");
- List<String> userIdList = faceService.getAllFace(groupId);
- return R.success(userIdList);
- }
- }
复制代码 后记
- com.jni.face包下,除了Face.java类,其他都是示例程序,可以视情况删除。
- models 文件夹里的模型可以按情况删除,详细可以查看文档。
- 项目启动后,你的控制台应该会收到SDK初始化的信息。并且你的libPath 目录下应该生成db文件夹,人脸数据将存储在这里。(db文件夹将生成在库文件所在目录。删除face.db后,初始化SDK时会自动生成,不需要额外操作。)
- 有生产需求的,但设备量不多,可以咸鱼买序列号。(官网最低100个起购)
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |