• 微信小程序 人脸识别登陆模块


    微信小程序---人脸识别登陆的实现

    关键词:微信小程序 人脸识别 百度云接口

    前言

    这是一篇关于一个原创微信小程序开发过程的原创文章。涉及到的核心技术是微信小程序开发方法和百度云人脸识别接口。小程序的主体是一个用于个人密码存储的密码管理器,在登陆注册阶段,需要调用百度云人脸识别接口以及百度云在线人脸库的管理接口。本文主要涉及登陆注册模块的实现,而且不需要PHP后台代码,完全在线调用接口实现,希望后来的你能有所收获!【自己玩玩可以,如果要实际生产使用,慎重!!!】

    注:之前存在的1.移动端无法使用(请打开手机调试功能,具体操作在文末);2.注册和登录需要多次尝试才能成功;3.小问题报错 问题,均已解决,目前可以正常使用。(这里要感谢@lllsp童鞋发现问题,并提出解决方法)

    步骤

    步骤 涉及接口(百度云)
    拍摄或者相册选择 并 上传比对样本照片到 人脸库 人脸库管理接口(main:人脸注册)
    拍摄照片并上传,云服务器在线比对 人脸库照片与上传图片的相似度 人脸识别接口
    获取返回结果(相似度) 人脸识别接口

    开发过程

    1.拍摄人脸图片上传至人脸库---注册

    准备工作:需要在百度云注册(或者直接用百度云盘app扫码登陆),并创建人脸识别的应用。(完全免费)

    具体如下:

    百度云:https://cloud.baidu.com/

    注册完成后(或者直接扫码登陆),进入管理控制台->产品服务->人工智能->人脸识别->创建应用->填写必要信息->立即创建

     至此,我们已经创建好了人脸识别的应用。接下来,进入应用列表,找到我们才新建的应用,查看人脸库,我们需要创建用户组(用来集中管理小程序的用户人脸照片)

    新建组(id不要太复杂,后面还要用的。)

    至此,我们已经完成了在云上的所有必要操作。下面,我们在小程序中,拍照上传即可。


     拍照上传

    需要在pages中新建一个目录,用来承载我们的登陆注册模块。就假定为 camera{camera.js camera.wxml camera.wxss camera.json}

    主要文件自然是 *.wxml 和 *.js 了。

    camera.wxml

     1 <!-- camera.wxml相机大小需要从重新设置 -->
     2 <camera
     3   device-position="front"
     4   flash="off"
     5   binderror="error"
     6   style=" 100%; height: 400px;"
     7 ></camera>
     8 
     9 <!-- 需要使用 button 来授权登录 -->
    10 <button
    11   wx:if="{{canIUse}}"
    12   open-type="getUserInfo"
    13   bindgetuserinfo="bindGetUserInfo"
    14   type="primary"
    15 >
    16   授权
    17 </button>
    18 <view wx:else>请升级微信版本</view>
    19 
    20 <!-- 拍照按钮 -->
    21 <button type="primary" bindtap="takePhoto"> 拍照 </button>
    22 
    23 <button bindtap='btnreg'> 注册须知 </button>

    我所谓的授权是,我需要获取用户微信的昵称来充当我人脸库照片的用户id,你可以不需要(设置成一样的,如果是只有一个人使用的话。)

    camera.js

    调用wxAPI takePhoto() 拍照并获取src -> wx.request() 访问百度云 用先前创建的应用的API Key & Screct Key 获取 access_token -> wx.request() 访问百度云 上传 所拍照片(要经过base64编码)详情可参考小程序API文档  以及 百度云API文档(接口已经于18年升级至v3)

      1 // camera.js
      2 const app = getApp()
      3 Page({
      4   data: {
      5     canIUse: wx.canIUse('button.open-type.getUserInfo'),
      6     nickName: "",
      7     src: "", //图片的链接
      8     token: "",
      9     base64: "",
     10     msg: ""
     11   },
     12   //拍照后调用的函数,用于获取token和上传图片进行注册
     13   myrquest: function () {
     14     var that = this;
     16     wx.request({
     17       url: 'https://aip.baidubce.com/oauth/2.0/token',
     18       data: {
     19         grant_type: 'client_credentials',
     20         client_id: '***************',//自己的API key
     21         client_secret: '******************' //自己的密码
     22       },
     23       header: {
     24         'Content-Type': 'application/json' // 默认值
     25       },
     26       success(res) {
     27         that.setData({
     28           token: res.data.access_token //获取到token
     29         }) 31         //上传人脸进行注册
     32         wx.request({
     33           url: 'https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=' + that.data.token,
     34           method: 'POST',
     35           data: {
     36             image: that.data.base64,
     37             image_type: 'BASE64',
     38             group_id: '**********', //自己的组id
     39             user_id: that.data.nickName //这里获取
     40           },
     41           header: {
     42             'Content-Type': 'application/json' // 默认值
     43           },
     44           success(res) { 46             var errorcode = res.data.error_code
     47             //做成功判断
     48             if (errorcode == 0) {
     49               wx.showToast({
     50                 title: '注册成功',
     51                 icon: 'success',
     52                 duration: 500
     53               })
     54               //注册成功,跳转到主界面
     55               wx.switchTab({
     56                 url: '../UI/ui'
     57               })
     58             }
     59           }
     60         })
     61       }
     62     })
     63   },
     64 
     65   //拍照
     66   takePhoto() {
     67     var that = this;
     68     //拍照
     69     const ctx = wx.createCameraContext()
     70     ctx.takePhoto({
     71       quality: 'medium',//使用small可以加快速度
     72       success: (res) => {
     73         that.setData({
     74           src: res.tempImagePath //获取图片
     75         })
     76 
     77         //图片base64编码
     78         wx.getFileSystemManager().readFile({
     79           filePath: that.data.src, //选择图片返回的相对路径
     80           encoding: 'base64', //编码格式
     81           success: res => { //成功的回调
     82             that.setData({
     83               base64: res.data
     84             })
     85             that.myrquest();//拍照之后,调用上传函数,获取token上传人脸
     86           }
     87         })
     88       } //拍照成功结束
     89 
     90     }) //调用相机结束
     91 
     92       //失败尝试
     93       wx.showToast({
     94         title: '注册中...',
     95         icon: 'loading',
     96         duration: 1000
     97       })
     98   },
     99   error(e) {
    100     console.log(e.detail)
    101   },
    102 
    103   //获取用户信息
    104   bindGetUserInfo: function (e) {
    105     this.setData({
    106       nickName: e.detail.userInfo.nickName
    107     })
    108     wx.showToast({
    109       title: '授权成功',
    110       icon: 'success',
    111       duration: 500
    112     })
    113   },
    114 
    115   //先授权登陆,再拍照注册
    116   btnreg: function () {
    117     wx.showModal({
    118       title: '注册须知',
    119       content: '先授权登陆,再拍照注册哦!网络可能故障,如果不成功,请再试一下!'
    120     })
    121   }
    122 
    123 })

    这里之前要多试几次,我之前以为可能由于网络的问题,会调用失败, 但其实是wx.request()是并发的,所以获取access_token和上传请求会冲突(可能没有获取到access_token就上传,会发生错误)。

    解决办法是:将获取token和上传图片封装成一个函数,且将上传图片的request放在获取token的成功回调中,这样可避免出现access token is invalid or no longer valid. 错误。

    (正确的代码就是上方给出的代码,不需要自己改)

    另外,要开启微信小程序 IDE 的 不校验合法域名的选项(设置->项目设置 -> 勾选 不校验......)

    至此,注册 就完成了(即获取用户昵称、拍照、上传人脸库注册。)



    2.拍照上传在线人脸识别---登陆

    找到指定用户组中与上传照片最相似的人脸并返回,比对结果。

    我们仍然需要再建立一个页面来承载我们的登陆相关操作。就假定为 camera2{camera2.js camera2.wxml camera2.wxss camera2.json}

    camera2.wxml

     1 <!-- camera.wxml -->
     2 <camera
     3   device-position="front"
     4   flash="off"
     5   binderror="error"
     6   style=" 100%; height: 300px;"
     7 ></camera>
     8 <button type="primary" bindtap="takePhoto">拍照</button>
     9 <view>预览</view>
    10 <image mode="widthFix" src="{{src}}"></image>

    camera2.js 与注册大同小异,区别是图片上传的接口不同(这次是 https://aip.baidubce.com/rest/2.0/face/v3/search 人脸搜素),获取access_token、拍照、照片base64编码都相同。

      1 // camera.js
      2 Page({
      3   data: {
      4     base64: "",
      5     token: "",
      6     msg: null,
      7     src: ''
      8   },
      9 
     10   //上传人脸进行验证(用于拍照后调用)
     11   myRequest: function () {
     12     var that = this;
     13   //acess_token获取
     14     wx.request({
     15       url: 'https://aip.baidubce.com/oauth/2.0/token', // 仅为示例,并非真实的接口地址
     16       data: {
     17         grant_type: 'client_credentials',
     18         client_id: '*********', //自己的API key
     19         client_secret: '*****************' //自己的Secrec Key
     20       },
     21       header: {
     22         'Content-Type': 'application/json' // 默认值
     23       },
     24       success(res) {
     25         that.setData({
     26           token: res.data.access_token //获取到token
     27           //上传人脸进行 比对
     28         })
     29         wx.request({
     30           url: 'https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=' + that.data.token,
     31           method: 'POST',
     32           data: {
     33             image: that.data.base64, //change:使用that
     34             image_type: 'BASE64',
     35             group_id_list: '**********' //自己的用户组id
     36           },
     37           header: {
     38             'Content-Type': 'application/json' // 默认值
     39           },
     40           success(res) {
     41             var errorcode = res.data.error_code
     42             if (errorcode == 0) //访问成功
     43             {
     44               var ulist = res.data.result
     45               //打印返回msg看看
     46               if (ulist.user_list != null) {
     47                 // console.log('ulist存在');
     48                 var result = ulist.user_list[0].score
     49                 if (result > 80) {
     50                   wx.showToast({
     51                     title: '验证通过',
     52                     icon: 'success',
     53                     duration: 500
     54                   })
     55                   //验证通过,跳转到主界面
     56                   wx.switchTab({
     57                     url: '../UI/ui'//自己的
     58                   })
     59                 } else {
     60                   console.log('不匹配')
     61                 }
     62               }
     63             } else {
     64               console.log('访问失败')
     65             }
     66           }
     67         });
     68       }
     69     })
     70   },
     71 
     72   //拍照并编码
     73   takePhoto() {
     74     var that = this;
     75     //拍照
     76     const ctx = wx.createCameraContext()
     77     ctx.takePhoto({
     78       quality: 'medium',//使用small可加快速度
     79       success: (res) => {
     80         that.setData({
     81           src: res.tempImagePath
     82         })
     83         //图片base64编码
     84         wx.getFileSystemManager().readFile({
     85           filePath: that.data.src, //选择图片返回的相对路径
     86           encoding: 'base64', //编码格式
     87           success: res => { //成功的回调
     88             that.setData({
     89               base64: res.data
     90             })
     91             that.myRequest();//调用函数进行token获取和图片上传验证
     92           }
     93         })
     94       }
     95     })
     96     //失败重试提醒
     97     wx.showToast({
     98       title: '验证中...',
     99       icon: 'loading',
    100       duration: 1000
    101     })
    102   },
    103   error(e) {
    104     console.log(e.detail)
    105   }
    106 })

     至此,我们的登陆也搞定了。


    注意:上述的 登陆注册 是一个小程序的一个模块。关系如下

    所以,需要在index页面中设置按钮,来跳转到注册以及登陆页面,然后注册登陆成功后,再跳转至其他功能页面。

    后记

    这次小程序实战,对我自己也是一个不小的挑战,对比各个云接口、看接口文档、查资料,耗费了大概十来天。但我相信大有裨益。另外,对我参考的博客和回答的诸位表示感谢。我们一起前进!

    参考资料

    【1】微信小程序开发文档

    【2】百度云接口文档.v3版

    打开小程序调试功能:

  • 相关阅读:
    通过docker-composer启动容器nginx,并完成spring.boot的web站点端口转发
    手写redis的docker文件,通过docker-compose配置redis
    基于Docker Compose搭建mysql主从复制(1主2从)
    ubuntu 14.04 挂载window共享目录
    asp.net mvc,基于aop实现的接口访问统计、接口缓存等
    自定义属性Attribute的运用
    表值参数的使用
    js的title提示
    Android之ViewPager中包含ViewFlipper时实现双滑动嵌套解决父控件干扰问题
    Android之ViewFlipper实现手动+自动切换图片(附加动画效果)
  • 原文地址:https://www.cnblogs.com/yocichen/p/10354035.html
Copyright © 2020-2023  润新知