前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于 Java 实现的人脸识别功能(附源码)

基于 Java 实现的人脸识别功能(附源码)

作者头像
程序员小富
发布于 2020-07-13 02:45:38
发布于 2020-07-13 02:45:38
2.7K10
代码可运行
举报
文章被收录于专栏:Java课堂Java课堂
运行总次数:0
代码可运行

人脸识别SDK

人脸识别技术是很复杂的,自己用Java手撕一个识别算法有点不切实际,毕竟实力不允许我这么嚣张,还是借助三方的SDK吧!

找了一圈发现一个免费的人脸识别SDK: ArcSoft:,地址:https://ai.arcsoft.com.cn

官网首页 -> 右上角开发者中心 -> 选择“人脸识别” -> 添加SDK,会生成APPIDSDK KEY后续会用到,根据需要选择不同的环境(本文基于windows环境),然后下载SDK是一个压缩包。

Java项目搭建

终于在我的苦苦搜寻之下终于,找到一个ArcSoftJava版本Demo,开源真是一件美好的事情,话不多说开干!

在这里插入图片描述

1、下载demo项目

github地址:https://github.com/xinzhfiu/ArcSoftFaceDemo,本地搭建数据库,创建表:user_face_info。这个表主要用来存人像特征,其中主要的字段 face_feature 用二进制类型 blob 存放人脸特征。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user_face_info
-- ----------------------------
DROP TABLE IF EXISTS `user_face_info`;
CREATE TABLE `user_face_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `group_id` int(11) DEFAULT NULL COMMENT '分组id',
  `face_id` varchar(31) DEFAULT NULL COMMENT '人脸唯一Id',
  `name` varchar(63) DEFAULT NULL COMMENT '名字',
  `age` int(3) DEFAULT NULL COMMENT '年纪',
  `email` varchar(255) DEFAULT NULL COMMENT '邮箱地址',
  `gender` smallint(1) DEFAULT NULL COMMENT '性别,1=男,2=女',
  `phone_number` varchar(11) DEFAULT NULL COMMENT '电话号码',
  `face_feature` blob COMMENT '人脸特征',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `fpath` varchar(255) COMMENT '照片路径',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `GROUP_ID` (`group_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;

2、修改application.properties文件

整个项目还是比较完整的,只需改一些配置即可启动,但有几点注意的地方,后边会重点说明。

config.arcface-sdk.sdk-lib-path:存放SDK压缩包中的三个.dll文件的路径

config.arcface-sdk.app-id :开发者中心的APPID

config.arcface-sdk.sdk-key :开发者中心的SDK Key

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
config.arcface-sdk.sdk-lib-path=d:/arcsoft_lib
config.arcface-sdk.app-id=8XMHMu71Dmb5UtAEBpPTB1E9ZPNTw2nrvQ5bXxBobUA8
config.arcface-sdk.sdk-key=BA8TLA9vVwK7G6btJh2A2FCa8ZrC6VWZLNbBBFctCz5R

# druid  本地的数据库地址
spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/xin-master?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.druid.username=junkang
spring.datasource.druid.password=junkang

3、根目录创建lib文件夹

在项目根目录创建文件夹 lib,将下载的SDK压缩包中的arcsoft-sdk-face-2.2.0.1.jar放入项目根目录

在这里插入图片描述

4、引入arcsoft依赖包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <dependency>
      <groupId>com.arcsoft.face</groupId>
      <artifactId>arcsoft-sdk-face</artifactId>
      <version>2.2.0.1</version>
      <scope>system</scope>
      <systemPath>${basedir}/lib/arcsoft-sdk-face-2.2.0.1.jar</systemPath>
</dependency>

pom.xml文件要配置includeSystemScope属性,否则可能会导致arcsoft-sdk-face-2.2.0.1.jar引用不到

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>

5、启动项目

到此为止配置完成,run Application文件启动

测试一下:http://127.0.0.1:8089/demo,如下页面即启动成功

操作

1、录入人脸图像

页面输入名称,点击摄像头注册调起本地摄像头,提交后将当前图像传入后台,识别提取当前人脸体征,保存至数据库。

2、人脸对比

录入完人脸图像后测试一下能否识别成功,提交当前的图像,发现识别成功相似度92%。但是作为程序员对什么事情都要持怀疑的态度,这结果不是老铁在页面写死的吧?

为了进一步验证,这回把脸挡住再试一下,发现提示“人脸不匹配”,证明真的有进行比对。

源码分析

简单看了一下项目源码,分析一下实现的过程:

页面和JS一看就是后端程序员写的,不要问我问为什么?懂的自然懂,哈哈哈 ~ ,

1、JS调起本地摄像头拍照,上传图片文件字符串

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    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引擎,顺着源码一路看下去,自己才疏学浅实在是没懂具体是个什么样的算法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 /*
    人脸添加
     */
    @RequestMapping(value = "/faceAdd", method = RequestMethod.POST)
    @ResponseBody
    public Result<Object> faceAdd(@RequestParam("file") String file, @RequestParam("groupId") Integer groupId, @RequestParam("name") String name) {

        try {

            //解析图片
            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);
    }

3、人像特征对比

人脸识别:将前端传入的图像经过人像特征提取后,和库中已存在的人像信息对比分析

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
    人脸识别
     */
    @RequestMapping(value = "/faceSearch", method = RequestMethod.POST)
    @ResponseBody
    public Result<FaceSearchResDto> faceSearch(String file, Integer groupId) throws Exception {
        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();
                ImageIO.write(bufImage, "jpg", outputStream);
                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);
    }

整个人脸识别功能的大致流程图如下:

总结

整个项目的设计思路比较清晰,难点在于人脸识别引擎前端JS部分代码,其他的功能比较平常。

赠人玫瑰手有余香,双手奉上源码地址:https://github.com/xinzhfiu/ArcSoftFaceDemo/,有任何技术问题,欢迎随时沟通

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员小富 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
人脸识别准确度能达到多少
人脸识别准确度能达到多少
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
在线图片文字识别html,识别文字在线_识别图片文字的在线方法是什么?[通俗易懂]
楼主给你说哦!其实没有必要咋先ocr文字识别的,可以使用专业的第三方软件来进行ocr文字识别的。
全栈程序员站长
2022/06/26
60.5K0
在线图片文字识别html,识别文字在线_识别图片文字的在线方法是什么?[通俗易懂]
手机里实现图片文字识别的实用方法[通俗易懂]
当然,这两种方法都可行,但是不够简单方便。手动输入太慢,语音识别又有点麻烦,如果普通话不好,识别很可能会出错。
全栈程序员站长
2022/09/05
4.7K0
手机里实现图片文字识别的实用方法[通俗易懂]
苹果手机识别图片文字方法「建议收藏」
识别图片文字的问题相信很多的小伙伴都是经历过的,一般遇到识别图片文字的问题,相信很多人都选择了用电脑打字进行转换,其实还有比这简单一下的方法吗,比如手机可以直接把图片文字识别出来,一起来看看操作方法吧。
全栈程序员站长
2022/08/12
9K0
苹果手机识别图片文字方法「建议收藏」
android 图片识别文字,安卓手机如何识别图片中的文字?一个方法轻松解决难题…
现在使用安卓手机的人并不少,有时在工作生活中,需要利用安卓手机将图片中的文字识别提取出来,这个时候你会吗?相信很多人的答案是否定的,那么安卓手机如何识别图片中的文字呢?下面我们就一起来看看吧。
全栈程序员站长
2022/08/11
10.3K0
【教程】如何批量图片文字识别软件,批量图片文字识别OCR软件系统,批量图片压缩,PDF批量转文字转图片
前段时间有人跟我讲说要批量图片(批量名片识别、批量照片识别等)识别,然后就下来研究了一下
全栈程序员站长
2022/09/07
45.4K0
【教程】如何批量图片文字识别软件,批量图片文字识别OCR软件系统,批量图片压缩,PDF批量转文字转图片
可以识别图片上的文字的小程序
微信上的小程序相信大家都不陌生,近年来,微信小程序从“跳一跳”之后,越发火了。由于小程序的出现,微信上的功能也逐渐增加了,今天就给大家介绍一个小程序,比较实用,它可以快速识别图片上的文字,这个小程序呢就叫“迅捷文字识别”。 这是一个比较智能的文字识别的小程序,它可以将识别出来的字汉英互译,还可以直接拍照翻译,接下来就给大家介绍一下这个小程序的操作方法。 1.首先,我们现在微信上找到这个程序,点击进入它的识别界面;
全栈程序员站长
2022/09/02
11.6K0
Python人工智能之图片识别,Python3一行代码实现图片文字识别[通俗易懂]
自学Python3第5天,今天突发奇想,想用Python识别图片里的文字。没想到Python实现图片文字识别这么简单,只需要一行代码就能搞定
全栈程序员站长
2022/08/11
2.6K0
Python人工智能之图片识别,Python3一行代码实现图片文字识别[通俗易懂]
三星识别文字_免费文字识别
百度 AI 实战营收官战(成都站),宣告百度 OCR 免费策略再次升级。百度通用文字识别服务的免费使用次数提升100倍,从每天500次提升至每天50000次;通用文字识别高精度版的免费使用次数提升10倍,从每天50次提升至每天500次。
全栈程序员站长
2022/09/01
25.5K0
图片文字识别怎么操作?图片文字识别怎么传出文件?
人们在工作的时候往往都是需要用到各种办公软件的,在办公软件中是需要用到很多图片和文字的,不过由于一些特殊原因,有些图片的文字人们是完全看不清楚或者看不完全的,所以就需要通过工具软件将图片上面的文字内容识别出来,相信大家平时办公或者学习的时候多少都是接触过的,那么图片文字识别怎么操作?图片文字识别怎么传出文件?下面小编就为大家带来详细介绍一下。
用户8739990
2021/07/23
40.7K0
图片文字识别怎么操作?图片文字识别怎么传出文件?
ABBYY FineReader2023OCR文字识别软件功能介绍
ABBYY FineReader是一款强大的OCR识别软件,ABBYY 轻松将任意文档转换成您需要的可编辑、引用、归档、搜索或分享的信息!ABBYY FineReader 通过将纸质文档、PDF文件和数码照片中的文字转换成可编辑、可搜索的文件,让您的电脑处理更具效率,摆脱从前的烦恼。告别耗时费力的手动输入和文件编辑:ABBYY FineReader提供无与伦比的文字识别精度、多语言识别和转换功能,同时完美保留原始文本的布局和格式。这就是最简单的OCR的方式,且本应如此!
用户7442547
2022/10/17
10.5K0
女友:啥,识别个文字还要付费?我立马用Python实现了一款免费版文字识别工具[通俗易懂]
有一天和女朋友聊天,翻着手机上的软件,看电影、看编程网站, 她说到:“这么多 APP,怎么就没一个做文字识别很方便的呢?
全栈程序员站长
2022/09/01
2.2K0
图像版PDF文件OCR识别转换为文本的3款免费工具软件
图像版PDF文件里面都是图片,要先通过OCR技术识别出文本,然后才能进行进一步处理编辑。下面是3个免费的PDF文件OCR识别软件工具:
AIGC部落
2024/06/24
6860
图像版PDF文件OCR识别转换为文本的3款免费工具软件
图片文字如何转换成Word,这个简单方法你得会
图片文字如何转换成Word?这是很多人在工作中都会遇到的问题,当你看到一个很好看的图片上面有你喜欢的文字,想把上面的文字保存下来,但是如果一个一个把字打出来那就太累了,今天呢就来给大家分享一个超级简单的方法,让你轻松搞定图片文字转Word,一起来看看吧。
高效办公
2019/06/11
11.7K0
图片文字如何转换成Word,这个简单方法你得会
这些文字识别神器,真香!!!
作者:不正经IO 公众号:不正经程序员 我们经常有识别文字的需求 比如看书时,我们想将书上的文字弄成电子的,发个朋友圈装一装 或者,需要将一些纸质文件上的文字转成电子的 如此种种 不知道你们平时用什
谭庆波
2019/05/21
5.3K0
这些文字识别神器,真香!!!
ABBYY16图片文字识别软件主要功能
ABBYY FineReader16是非常好的一款 OCR 识别软件(可以识别不可编辑的 PDF 和图片文件),操作非常简单。ABBYY FineReader 16是一款知名的OCR文字识别软件(图片文字识别)。ABBYY 15采用了ABBYY最新推出的基于AI的OCR技术,可以更轻松地在同一工作流程中对各种文档进行数字化、检索、编辑、加密、共享和协作。
用户7442547
2023/02/23
10.1K0
Android上图片文字识别
最近做了一款Android应用需要输入大量的数据,为了提高体验我想了很多种输入数据的方式,最终采用了两种:二维码扫描和图片识别。前者顾名思义有个短板,就是需要生成二维码,下面就介绍下图片文字识别实现。
全栈程序员站长
2022/07/01
33.7K0
Android上图片文字识别
图片转文字可以用什么工具 能识别英文吗
随着当代社会互联网的普及,很多人看书或者写作文、日记的时候,都会选择用手机。但可能经常都会有一个烦恼,就是找到自己想要的资料,但是无法复制粘贴,如果是很长的文章就会非常的耗时间。那么这个时候,如果能够直接把图片转文字就会非常方便。
用户8739990
2021/07/12
12.5K0
图片转文字可以用什么工具 能识别英文吗
懒得打字?这两款文字识别小程序,解放你的双手
在平时的工作和学习生活中,一旦碰到一些需要拷贝下来的图片上的文字,通常你会怎么做呢?
知晓君
2018/08/01
2.6K0
懒得打字?这两款文字识别小程序,解放你的双手
python识别文字位置_如何利用Python识别图片中的文字
不知道大家有没有遇到过这样的问题,就是在某个软件或者某个网页里面有一篇文章,你非常喜欢,但是不能复制。或者像百度文档一样,只能复制一部分,这个时候我们就会选择截图保存。但是当我们想用到里面的文字时,还是要一个字一个字打出来。那么我们能不能直接识别图片中的文字呢?答案是肯定的。
全栈程序员站长
2022/08/30
29.2K0
python识别文字位置_如何利用Python识别图片中的文字
PDF文字识别三步搞定,这样的方法你该知道
在我们工作中会处理很多的文档,但是如果给你一堆PDF图片让你全部整理为电子档,其实你的内心一定是崩溃的,手打的话工作量真的太大了,而且很浪费时间时间,但PDF文字识别就能轻松帮你解决这个问题,下来就来为大家介绍PDF文字识别三步搞定的简单方法哦,还在等什么,赶紧来学习吧。
高效办公
2019/05/27
10K0
PDF文字识别三步搞定,这样的方法你该知道
推荐阅读
相关推荐
在线图片文字识别html,识别文字在线_识别图片文字的在线方法是什么?[通俗易懂]
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验