人脸识别SDK调用与分析

该demo时是基于springboot的人脸识别和后期判断的小项目,利用的是第三发的虹软人脸识别的SDK。
下面主要展示页面功能:照相或照片的方式解析图片,提取特征;照相或照片的方式对比图片,判断相似度;
在这里插入图片描述
在这里插入图片描述
在引入相关的依赖后和输入想过的appid和sdk key后,我们主要对调用sdk识别的代码进行分析
1、JS调用摄像头拍照,或从本地文件上传
将照片或者照片文件转化为64位编码,向后端传送

    function getMedia() {
        $("#mainDiv").empty();
        let videoComp = " <video id='video' width='500px' height='500px' autoplay='autoplay' style='margin-top: 20px'></video><canvas id='canvas' width='500px' height='500px' style='display: none'></canvas>";
        $("#mainDiv").append(videoComp);
 
        let constraints = {
            video: {width: 500, height: 500},
            audio: true
        };
        //获得video摄像头区域
        let video = document.getElementById("video");
        //这里介绍新的方法,返回一个 Promise对象
        // 这个Promise对象返回成功后的回调函数带一个 MediaStream 对象作为其参数
        // then()是Promise对象里的方法
        // then()方法是异步执行,当then()前的方法执行完后再执行then()内部的程序
        // 避免数据没有获取到
        let promise = navigator.mediaDevices.getUserMedia(constraints);
        promise.then(function (MediaStream) {
            video.srcObject = MediaStream;
            video.play();
        });
 
        // var t1 = window.setTimeout(function() {
        //     takePhoto();
        // },2000)
    }
//拍照事件
    function takePhoto() {
        let mainComp = $("#mainDiv");
        if(mainComp.has('video').length)
        {
            let userNameInput = $("#userName").val();
            if(userNameInput == "")
            {
                alert("姓名不能为空!");
                return false;
            }
            //获得Canvas对象
            let video = document.getElementById("video");
            let canvas = document.getElementById("canvas");
            let ctx = canvas.getContext('2d');
            ctx.drawImage(video, 0, 0, 500, 500);
            var formData = new FormData();
            var base64File = canvas.toDataURL();
            var userName = $("#userName").val();
            formData.append("file", base64File);
            formData.append("name", userName);
            formData.append("groupId", "101");
            $.ajax({
                type: "post",
                url: "/faceAdd",
                data: formData,
                contentType: false,
                processData: false,
                async: false,
                success: function (text) {
                    var res = JSON.stringify(text)
                    if (text.code == 0) {
                        alert("注册成功")
                    } else {
                        alert(text.message)
                    }
                },
                error: function (error) {
                    alert(JSON.stringify(error))
                }
            });
        }
        else{
            var formData = new FormData();
            let userName = $("#userName").val();
            formData.append("groupId", "101");
            var file = $("#file0")[0].files[0];
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function () {
            var base64 = reader.result;
            formData.append("file", base64);
            formData.append("name",userName);
                $.ajax({
                    type: "post",
                    url: "/faceAdd",
                    data: formData,
                    contentType: false,
                    processData: false,
                    async: false,
                    success: function (text) {
                        var res = JSON.stringify(text)
                        if (text.code == 0) {
                            alert("注册成功")
                        } else {
                            alert(text.message)
                        }
                    },
                    error: function (error) {
                        alert(JSON.stringify(error))
                    }
                });
                location.reload();
            }
        }
 
    }

2、后端解析图片,提取人像特征
人像特征的提取主要是靠FaceEngine引擎
人脸添加

/*
    人脸添加
     */
    @RequestMapping(value = "/faceAdd", method = RequestMethod.POST)
    @ResponseBody
    public Result<Object> faceAdd(@RequestParam("file") String file, @RequestParam("groupId") Integer groupId, @RequestParam("name") String name) {

        try {
            if (file == null) {
                return Results.newFailedResult("file is null");
            }
            if (groupId == null) {
                return Results.newFailedResult("groupId is null");
            }
            if (name == null) {
                return Results.newFailedResult("name is null");
            }

            byte[] decode = Base64.decode(base64Process(file));
            ImageInfo imageInfo = ImageFactory.getRGBData(decode);

            //人脸特征获取
            byte[] bytes = faceEngineService.extractFaceFeature(imageInfo);
            if (bytes == null) {
                return Results.newFailedResult(ErrorCodeEnum.NO_FACE_DETECTED);
            }

            UserFaceInfo userFaceInfo = new UserFaceInfo();
            userFaceInfo.setName(name);
            userFaceInfo.setGroupId(groupId);
            userFaceInfo.setFaceFeature(bytes);
            userFaceInfo.setFaceId(RandomUtil.randomString(10));

            //人脸特征插入到数据库
            userFaceInfoService.insertSelective(userFaceInfo);

            logger.info("faceAdd:" + name);
            return Results.newSuccessResult("");
        } catch (Exception e) {
            logger.error("", e);
        }
        return Results.newFailedResult(ErrorCodeEnum.UNKNOWN);
    }

在人脸添加的控制层,用到了service层逻辑处理,大致看注释就能明白

@Override
    public byte[] extractFaceFeature(ImageInfo imageInfo) throws InterruptedException {

        FaceEngine faceEngine = null;
        try {
            //获取引擎对象
            faceEngine = faceEngineObjectPool.borrowObject();

            //人脸检测得到人脸列表
            List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();

            //人脸检测
            int i = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);

            if (CollectionUtil.isNotEmpty(faceInfoList)) {
                FaceFeature faceFeature = new FaceFeature();
                //提取人脸特征
                faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);

                return faceFeature.getFeatureData();
            }
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            if (faceEngine != null) {
                //释放引擎对象
                faceEngineObjectPool.returnObject(faceEngine);
            }

        }

        return null;
    }

然后将faceFeature存入数据库即可。

下面是人脸对比分析,性别年龄相似度分析
先看controller层

/*
    人脸识别
     */
    @RequestMapping(value = "/faceSearch", method = RequestMethod.POST)
    @ResponseBody
    public Result<FaceSearchResDto> faceSearch(String file, Integer groupId) throws Exception {


        if (groupId == null) {
            return Results.newFailedResult("groupId is null");
        }
        byte[] decode = Base64.decode(base64Process(file));
        BufferedImage bufImage = ImageIO.read(new ByteArrayInputStream(decode));
        ImageInfo imageInfo = ImageFactory.bufferedImage2ImageInfo(bufImage);


        //人脸特征获取
        byte[] bytes = faceEngineService.extractFaceFeature(imageInfo);
        if (bytes == null) {
            return Results.newFailedResult(ErrorCodeEnum.NO_FACE_DETECTED);
        }

        //人脸比对,获取比对结果
        List<FaceUserInfo> userFaceInfoList = faceEngineService.compareFaceFeature(bytes, groupId);


        if (CollectionUtil.isNotEmpty(userFaceInfoList)) {

            FaceUserInfo faceUserInfo = userFaceInfoList.get(0);
            FaceSearchResDto faceSearchResDto = new FaceSearchResDto();
            BeanUtil.copyProperties(faceUserInfo, faceSearchResDto);
            List<ProcessInfo> processInfoList = faceEngineService.process(imageInfo);

            if (CollectionUtil.isNotEmpty(processInfoList)) {

                //人脸检测
                List<FaceInfo> faceInfoList = faceEngineService.detectFaces(imageInfo);
                int left = faceInfoList.get(0).getRect().getLeft();
                int top = faceInfoList.get(0).getRect().getTop();
                int width = faceInfoList.get(0).getRect().getRight() - left;
                int height = faceInfoList.get(0).getRect().getBottom() - top;

                Graphics2D graphics2D = bufImage.createGraphics();
                graphics2D.setColor(Color.RED);//红色
                BasicStroke stroke = new BasicStroke(5f);
                graphics2D.setStroke(stroke);
                graphics2D.drawRect(left, top, width, height);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                System.out.println("111");
                System.out.println(bufImage.getType());
                ImageIO.write(bufImage, "gif", outputStream);
                System.out.println("111");
                byte[] bytes1 = outputStream.toByteArray();

                faceSearchResDto.setImage("data:image/jpeg;base64," + Base64Utils.encodeToString(bytes1));
                faceSearchResDto.setAge(processInfoList.get(0).getAge());
                faceSearchResDto.setGender(processInfoList.get(0).getGender().equals(1) ? "女" : "男");

            }

            return Results.newSuccessResult(faceSearchResDto);
        }

        return Results.newFailedResult(ErrorCodeEnum.FACE_DOES_NOT_MATCH);
    }

再看service层

@Override
    public List<FaceUserInfo> compareFaceFeature(byte[] faceFeature, Integer groupId) throws InterruptedException, ExecutionException {
        List<FaceUserInfo> resultFaceInfoList = Lists.newLinkedList();//识别到的人脸列表

        FaceFeature targetFaceFeature = new FaceFeature();
        targetFaceFeature.setFeatureData(faceFeature);
        List<FaceUserInfo> faceInfoList = userFaceInfoMapper.getUserFaceInfoByGroupId(groupId); //从数据库中取出人脸库
        List<List<FaceUserInfo>> faceUserInfoPartList = Lists.partition(faceInfoList, 1000);//分成1000一组,多线程处理
        CompletionService<List<FaceUserInfo>> completionService = new ExecutorCompletionService(executorService);
        for (List<FaceUserInfo> part : faceUserInfoPartList) {
            completionService.submit(new CompareFaceTask(part, targetFaceFeature));
        }
        for (int i = 0; i < faceUserInfoPartList.size(); i++) {
            List<FaceUserInfo> faceUserInfoList = completionService.take().get();
            if (CollectionUtil.isNotEmpty(faceInfoList)) {
                resultFaceInfoList.addAll(faceUserInfoList);
            }
        }

        resultFaceInfoList.sort((h1, h2) -> h2.getSimilarValue().compareTo(h1.getSimilarValue()));//从大到小排序

        return resultFaceInfoList;
    }


    private class CompareFaceTask implements Callable<List<FaceUserInfo>> {

        private List<FaceUserInfo> faceUserInfoList;
        private FaceFeature targetFaceFeature;


        public CompareFaceTask(List<FaceUserInfo> faceUserInfoList, FaceFeature targetFaceFeature) {
            this.faceUserInfoList = faceUserInfoList;
            this.targetFaceFeature = targetFaceFeature;
        }

        @Override
        public List<FaceUserInfo> call() throws Exception {
            FaceEngine faceEngine = null;
            List<FaceUserInfo> resultFaceInfoList = Lists.newLinkedList();//识别到的人脸列表
            try {
                faceEngine = faceEngineObjectPool.borrowObject();
                for (FaceUserInfo faceUserInfo : faceUserInfoList) {
                    FaceFeature sourceFaceFeature = new FaceFeature();
                    sourceFaceFeature.setFeatureData(faceUserInfo.getFaceFeature());
                    FaceSimilar faceSimilar = new FaceSimilar();
                    faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
                    Integer similarValue = plusHundred(faceSimilar.getScore());//获取相似值
                    if (similarValue > passRate) {//相似值大于配置预期,加入到识别到人脸的列表

                        FaceUserInfo info = new FaceUserInfo();
                        info.setName(faceUserInfo.getName());
                        info.setFaceId(faceUserInfo.getFaceId());
                        info.setSimilarValue(similarValue);
                        resultFaceInfoList.add(info);
                    }
                }
            } catch (Exception e) {
                logger.error("", e);
            } finally {
                if (faceEngine != null) {
                    faceEngineObjectPool.returnObject(faceEngine);
                }
            }

            return resultFaceInfoList;
        }

大致流程
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要下载树莓派人脸识别SDK,首先需要在官方网站或其他可信的技术网站上搜索相关的SDK。可以使用搜索引擎,输入关键词“树莓派人脸识别SDK下载”来查找相关软件。挑选一个合适的SDK下载链接,确保其与树莓派设备兼容。 点击下载链接后,进入下载页面,选择适用于树莓派的版本,通常会有树莓派的图标或者在系统要求中提到树莓派。确认无误后,点击下载按钮。 下载完成后,将SDK文件保存到树莓派的合适位置,可以选择将其保存到SD卡或者任意目录。 根据SDK的具体要求和文档,进行安装和配置。这一步可以参考SDK提供的官方文档或者操作指南来进行。 安装和配置完成后,就可以开始使用树莓派人脸识别SDK了。根据SDK的使用方式,编写代码,实现人脸识别的功能。可以通过调用SDK的API来实现人脸检测、识别和比对等功能。 在使用SDK的过程中,可以根据需求进行自定义设置,如设置阈值、调整人脸识别的精度和速度,以及配置相机和摄像头等参数。 最后,根据自己的实际应用场景,将人脸识别功能好好利用起来,可以用于监控系统、门禁系统、智能家居等方面。 总之,要下载树莓派人脸识别SDK,先搜索并选择合适的SDK,下载并安装到树莓派上,然后根据具体文档进行配置和编程,最终实现人脸识别的功能。 ### 回答2: 要下载树莓派的人脸识别SDK,首先需要确定你所需要的SDK具体是哪一家公司或开发者提供的。树莓派作为一款开源硬件,拥有广泛的支持和社区,因此有许多不同的人脸识别SDK可供选择。 一种下载的方式是通过访问官方网站下载。首先,你需要搜索相关的人脸识别SDK提供商的官方网站。在网站的下载页面,通常会提供对于树莓派的支持和下载链接。你可以浏览他们的网站,找到适用于树莓派的SDK版本并下载。在下载之前,确保你选择的版本和树莓派的硬件和操作系统相匹配。 另一种方式是通过基于树莓派的操作系统(如Raspbian)的软件库进行下载。树莓派的操作系统通常会提供一些常用的SDK,并且可以通过包管理器(如apt-get)来安装。你可以在命令行中运行适当的命令来搜索和安装树莓派人脸识别SDK。确保你的操作系统已经更新到最新版本,以保证软件库中有最新的SDK可供下载。 无论你选择哪种方式,下载时要确保选择信誉良好的提供商,以获得更好的技术支持和保障。在下载前,建议查看一些用户对该SDK的评价和反馈,了解其性能和可靠性。另外,阅读相关的文档和教程可以帮助你更好地了解和使用该SDK,以便你能够更好地将其整合到你的树莓派项目中。 ### 回答3: 要下载树莓派人脸识别SDK非常简单。首先,你需要打开树莓派的操作系统,确保你已经连接到互联网。然后,使用浏览器访问相关的网站或官方社区。在搜索框中输入“树莓派人脸识别SDK下载”,然后点击搜索按钮。 在搜索结果中,你会看到各种不同的下载选项。注意选择适合你需求的版本和文件类型。一般来说,官方社区或软件开发者网站是最安全和可靠的下载来源。 点击选定的下载链接后,等待文件下载完成。下载时间取决于你的互联网连接速度和文件大小。 一旦下载完成,你需要找到文件保存的位置并解压缩。这通常涉及到右键点击文件并选择“解压缩”选项。如果你不熟悉解压缩文件的操作,可以搜索相关的指导教程。 解压缩后,你会得到一个包含SDK的文件夹。你可以将该文件夹移动到你喜欢的位置,以便方便访问。 现在,你已经成功下载和准备好使用树莓派人脸识别SDK了。你可以从文件夹中找到示例代码和文档,以帮助你开始开发或使用该SDK。 希望这个简单的指南对你有所帮助!祝你下载并使用SDK时顺利!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值