欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

做一个人脸识别登录功能

程序员文章站 2022-06-26 16:19:30
前天晚上散步到一个大学公寓门口,发现公寓的大门口都安装了人脸识别的门禁,就有种强烈的欲望 想要学习一下 哈哈,刚好也在做项目就想运用到这个技术—于是便有了开端。视觉智能——人脸识别基于阿里云的视觉只能开放平台,提供的人脸一对一服务进行编写。在开发之前需要准备:1.阿里云账号2.开通阿里云的OSS对象存储权限3.开通用户的管理视觉智能的权限先看一下我做成的效果图把识别失败识别成功 思路通过上传到服务器对比上传图片的人脸,和数据库图片的人脸进行比较,判断是否是同一人。开通用户....

前天晚上散步到一个大学公寓门口,发现公寓的大门口都安装了人脸识别的门禁,就有种强烈的欲望 想要学习一下 哈哈,刚好也在做项目就想运用到这个技术—于是便有了开端。

视觉智能——人脸识别

基于阿里云的视觉只能开放平台,提供的人脸一对一服务进行编写。
在开发之前需要准备:
1.阿里云账号
2.开通阿里云的OSS对象存储权限
3.开通用户的管理视觉智能的权限

先看一下我做成的效果图把

做一个人脸识别登录功能
识别失败做一个人脸识别登录功能
识别成功 做一个人脸识别登录功能

思路

通过上传到服务器对比上传图片的人脸,和数据库图片的人脸进行比较,判断是否是同一人。

开通用户用户的OSS对象存储权限,需要将两张图片上传到OSS的Bucket库中才能进行比对。

开通用户的视觉智能权限才能进行使用此服务。

注意

在为创建用户时要注意勾选 访问方式下的:编程式访问,在创建用户成功之后会生成一个AccessKey 密钥信息,要保存下来后面是不会显示value的。

开通OSS对象存储服务后,需要创建一个Bucket库它是用于存放我们上传的图片位置的,目前视觉智能服务只支持 OSS库的区域 为 华东2(上海区)

以上工作准备完毕就开始开始编码的工作了!

页面

可以看到效果图,通过调用本地的摄像头拍照,然后将图片上传到服务器,跟数据库的图片信息进行比较。

slrb.html


<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" th:href="@{./lib/layui/css/layui.css}" media="all">
    <link rel="stylesheet" type="text/css" th:href="@{./css/dialog.css}" />
    <title>调用拍照</title>
</head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<style>
    #capture{
        position: absolute;
        right: 190px;
        bottom: -40px;

    }
    #video{
        position: absolute;
        right: 0;
        top: 0;
    }
    #img{
        position: absolute;
        left: 0;
        top: 0;
    }
    .auto{
        position: absolute;
        left: 50%;
        top: 50%;
        height: 320px;
        margin-top: -160px;
    }
    #sure{
        position: absolute;
        left: 210px;
        bottom: -40px;

    }
    button{
        cursor: pointer;
        margin: 0 auto;
        border: 1px solid #f0f0f0;
        background: #5CACEE;
        color: #FFF;
        width: 100px;
        height: 36px;
        line-height: 36px;
        border-radius: 8px;
        text-align: center;
        /*禁止选择*/
        -webkit-touch-callout: none; /* iOS Safari */
        -webkit-user-select: none; /* Chrome/Safari/Opera */
        -khtml-user-select: none; /* Konqueror */
        -moz-user-select: none; /* Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
        user-select: none; /* Non-prefixed version, currently not supported by any browser */
    }

</style>
<body style="background-color: #2B2E37">
<h1 style="color: whitesmoke;text-align: center;font-size: 30px;margin-top: 50px">后台人脸识别登录系统</h1>
<div class="auto">
    <video id="video" width="480" height="320" autoplay ></video>
    <canvas id="canvas" width="480" height="320" style="display: none;"></canvas>
    <img th:src="@{./images/timg2.jpg}" id="img"  width="480" height="320" style="margin-left: 80px;">
    <div>
        <button id="capture" title="点击进行拍照">拍照</button>
    </div>
    <div>
        <button id="sure" title="是否用这张图片进行验证">确认</button>
    </div>
</div>

<script type="text/javascript" th:src="@{./js/dialog.js}"></script>
<script type="text/javascript">
    var file ,stream;
    var isCount=0;
    //访问用户媒体设备的兼容方法
    function getUserMedia(constraints, success, error) {
        if (navigator.mediaDevices.getUserMedia) {
            //最新的标准API
            navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
        } else if (navigator.webkitGetUserMedia) {
            //webkit核心浏览器
            navigator.webkitGetUserMedia(constraints,success, error)
        } else if (navigator.mozGetUserMedia) {
            //firfox浏览器
            navigator.mozGetUserMedia(constraints, success, error);
        } else if (navigator.getUserMedia) {
            //旧版API
            navigator.getUserMedia(constraints, success, error);
        }
    }

    let video = document.getElementById('video');
    let canvas = document.getElementById('canvas');
    let context = canvas.getContext('2d');

    function success(stream) {
        //兼容webkit核心浏览器
        let CompatibleURL = window.URL || window.webkitURL;
        //将视频流设置为video元素的源
        console.log(stream);
        stream = stream;
        //video.src = CompatibleURL.createObjectURL(stream);
        video.srcObject = stream;
        video.play();
    }

    function error(error) {
        console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
    }

    if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
        //调用用户媒体设备, 访问摄像头
        getUserMedia({video : {width: 480, height: 320}}, success, error);
    } else {
        alert('不支持访问用户媒体');
    }
    // base64转文件
    document.getElementById('capture').addEventListener('click', function () {
        context.drawImage(video, 0, 0, 480, 320);
        // 获取图片base64链接
        var image = canvas.toDataURL('image/png');
        // 定义一个img
        var img = document.getElementById("img");
        //设置属性和src
        //img.id = "imgBoxxx";
        img.src = image;
        //将图片添加到页面中
        //document.body.appendChild(img);
        function dataURLtoFile(dataurl, filename) {
            var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            file = new File([u8arr], filename, {type: mime});
            return new File([u8arr], filename, {type: mime});
        }
        console.log(dataURLtoFile(image, 'aa.png'));
    })

    document.getElementById('sure').addEventListener('click', function () {
      
        var formData = new FormData();
        formData.append("file",file); //file 追加到表单
        jQuery.ajax({
            type: "POST", // 数据提交类型
            url: "/xxxxxx", // 发送地址
            data: formData, //发送数据
            async: true, // 是否异步
            processData: false, //processData 默认为false,当设置为true的时候,jquery ajax 提交的时候不会序列化 data,而是直接使用data
            contentType: false,
            success:function(data){
               le.log(‘success`);
               
            },
            error:function(e){

                console.log("不成功"+e);
            }
        });
       
</body>
</html>

然后就是文件上传到OSS对象存储的服务上了

//依赖
<aliyun.oss.version>3.4.2</aliyun.oss.version>
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>${aliyun.oss.version}</version>
</dependency>

封装的一个简单的文件上传工具类,返回的是文件上传后的路径!

package org.boy.api;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: JinXu
 * @Date: 2020/11/07/23:30
 */
@Component
public class AliyunOssTool {
    /**
     * 阿里云 oss 站点
     */
    @Value("${oss.endpoint}")
    protected String endpoint;
    /**
     * 阿里云 oss 资源访问 url
     */
    @Value("${oss.url}")
    protected String url;
    /**
     * 阿里云 oss 公钥
     */
    @Value("${oss.accessKeyId}")
    protected String accessKeyId;
    /**
     * 阿里云 oss 私钥
     */
    @Value("${oss.accessKeySecret}")
    protected String accessKeySecret;
    /**
     * 阿里云 oss 文件根目录
     */
    @Value("${oss.bucketName}")
    protected String bucketName;

    /**
     * 阿里云  regionld
     */
    @Value("${oss.regionld}")
    protected   String regionld;
    public String uploadOss(InputStream inputStream,String fileName){

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName,inputStream);
        // 上传文件。
        ossClient.putObject(putObjectRequest);
        // 设置URL过期时间为1小时。
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        String url=ossClient.generatePresignedUrl(bucketName,fileName,expiration).toString();
        // 关闭OSSClient。
        ossClient.shutdown()

        return url;
    }
}

编写人脸对比接口,调用阿里云的服务进行比对

<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-facebody -->
<alirlsb.version>1.2.0</alirlsb.version>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-facebody</artifactId>
    <version>${alirlsb.version}</version>
</dependency>

主要步骤:

//上面提到报保存用户的   AccessKey键值----
DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", "AccessKeyId", "secret");
IAcsClient client = new DefaultAcsClient(profile);

String urlA="";//这个是你 需要比对数据库的图片地址
String urlB="";//人脸识别拍的照片上传后的图片地址
CompareFaceRequest request = new CompareFaceRequest();
request.setRegionId("cn-shanghai");
request.setImageURLA(urlA);
request.setImageURLB(urlB);
try {
    CompareFaceResponse response = client.getAcsResponse(request);
    System.out.println(new Gson().toJson(response));
    //返回的 对比相似读的 值
    System.out.println(response.getData().getConfidence());
} catch (ServerException e) {
    e.printStackTrace();
} catch (ClientException e) {
    System.err.println("ErrCode:" + e.getErrCode());
    System.err.println("ErrMsg:" + e.getErrMsg());
    System.err.println("RequestId:" + e.getRequestId());
}

大概的流程就是这些了,可以根据需求进行改写,比如写成一个一对多的比对校验,多对一人脸识别…

如有错误望指正,一起学习,共同进步!

本文地址:https://blog.csdn.net/weixin_44924238/article/details/109561018