【转】微信小程序实现人脸识别登陆的示例代码
原文地址:https://www.jb51.net/article/158886.htm
前言
这是一篇关于一个原创微信小程序开发过程的原创文章。涉及到的核心技术是微信小程序开发方法和百度云人脸识别接口。小程序的主体是一个用于个人密码存储的密码管理器,在登陆注册阶段,需要调用百度云人脸识别接口以及百度云在线人脸库的管理接口。本文主要涉及登陆注册模块的实现,而且不需要PHP后台代码,完全在线调用接口实现,希望后来的你能有所收获!
步骤
步骤 | 涉及接口(百度云) |
拍摄或者相册选择 并 上传比对样本照片到 人脸库 | 人脸库管理接口(main:人脸注册) |
拍摄照片并上传,云服务器在线比对 人脸库照片与上传图片的相似度 | 人脸识别接口 |
获取返回结果(相似度) | 人脸识别接口 |
开发过程
1.拍摄人脸图片上传至人脸库—注册
准备工作:需要在百度云注册(或者直接用百度云盘app扫码登陆),并创建人脸识别的应用。(完全免费)
具体如下:
注册完成后(或者直接扫码登陆),进入管理控制台->产品服务->人工智能->人脸识别->创建应用->填写必要信息->立即创建
至此,我们已经创建好了人脸识别的应用。接下来,进入应用列表,找到我们才新建的应用,查看人脸库,我们需要创建用户组(用来集中管理小程序的用户人脸照片)
新建组(id不要太复杂,后面还要用的。)
至此,我们已经完成了在云上的所有必要操作。下面,我们在小程序中,拍照上传即可。
拍照上传
需要在pages中新建一个目录,用来承载我们的登陆注册模块。就假定为 camera{camera.js camera.wxml camera.wxss camera.json}
主要文件自然是 *.wxml 和 *.js 了。
camera.wxml
- <!-- camera.wxml相机大小需要从重新设置 -->
- <camera device-position="front" flash="off" binderror="error" style="width:100%;height:400px;"></camera>
- <!-- 需要使用 button 来授权登录 -->
- <button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo" type="primary">
- 授权
- </button>
- <view wx:else>请升级微信版本</view>
- <!-- 拍照按钮 -->
- <button type="primary" bindtap="takePhoto"> 拍照 </button>
- <button bindtap=\'btnreg\'> 注册须知 </button>
camera.js
调用wxAPI takePhoto() 拍照并获取src -> wx.request() 访问百度云 用先前创建的应用的API Key & Screct Key 获取 access_token ->wx.request() 访问百度云 上传 所拍照片(要经过base64编码)详情可参考小程序API文档 以及 百度云API文档(接口以及于18年升级至v3)
- // camera.js
- const app = getApp()
- Page({
- data: {
- canIUse: wx.canIUse(\'button.open-type.getUserInfo\'),
- nickName: "",
- src: "",//图片的链接
- baidutoken: "",
- base64: "",
- msg: ""
- },
- //拍照
- takePhoto() {
- var that = this;
- //拍照
- const ctx = wx.createCameraContext()
- ctx.takePhoto({
- quality: \'high\',
- success: (res) => {
- this.setData({
- src: res.tempImagePath//获取图片
- })
- //图片base64编码
- wx.getFileSystemManager().readFile({
- filePath: this.data.src, //选择图片返回的相对路径
- encoding: \'base64\', //编码格式
- success: res => { //成功的回调
- this.setData({
- base64: res.data
- })
- }
- })
- this.getBaiduToken();
- }//拍照成功结束
- })//调用相机结束
- //失败尝试
- wx.showToast({
- title: \'请重试\',
- icon: \'loading\',
- duration: 500
- })
- },
- error(e) {
- console.log(e.detail)
- },
- getBaiduToken:function(){
- var that=this;
- //acess_token获取,qs:需要多次尝试
- wx.request({
- url: \'https://aip.baidubce.com/oauth/2.0/token\', //是真实的接口地址
- data: {
- grant_type: \'client_credentials\',
- client_id: \'xxx\',//用你创建的应用的API Key
- client_secret: \'xx\'//用你创建的应用的Secret Key
- },
- header: {
- \'Content-Type\': \'application/json\' // 默认值
- },
- success(res) {
- that.setData({
- baidutoken: res.data.access_token//获取到token
- })
- that.uploadPhoto();
- }
- })
- },
- uploadPhoto:function()
- {
- var that=this;
- //上传人脸进行注册-----test
- wx.request({
- url: \'https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=\' + this.data.baidutoken,
- method: \'POST\',
- data: {
- image: this.data.base64,
- image_type: \'BASE64\',
- group_id: \'tingdemo\',//自己建的用户组id
- user_id: \'ting\'//这里获取用户昵称
- },
- header: {
- \'Content-Type\': \'application/json\' // 默认值
- },
- success(res) {
- that.setData({
- msg: res.data.error_msg
- })
- console.log(that.data.msg)
- //做成功判断
- if (that.data.msg == \'SUCCESS\') {//微信js字符串请使用单引号
- wx.showToast({
- title: \'注册成功\',
- icon: \'success\',
- duration: 2000
- })
- wx.switchTab({
- url: \'../UI/ui\',
- })
- }
- }
- })
- },
- //获取用户信息
- bindGetUserInfo: function (e) {
- this.setData({
- nickName: e.detail.userInfo.nickName
- })
- debugger;
- wx.showToast({
- title: \'授权成功\',
- icon: \'success\',
- duration: 1000
- })
- },
- //先授权登陆,再拍照注册
- btnreg: function () {
- wx.showModal({
- title: \'注册须知\',
- content: \'先授权登陆,再拍照注册哦!网络可能故障,如果不成功,请再试一下!\',
- })
- }
- })
这里要多试几次,我以为可能由于网络的问题,会调用失败, 但其实是wx.request()是并发的,所以获取access_token和上传请求会冲突(可能没有获取到access_token就上传,会发生错误)。
另外,要开启微信小程序 IDE 的 不校验合法域名的选项(设置->项目设置 -> 勾选 不校验……)
至此,注册 就完成了(即获取用户昵称、拍照、上传人脸库注册。)
2.拍照上传在线人脸识别—登陆
找到指定用户组中与上传照片最相似的人脸并返回,比对结果。
我们仍然需要再建立一个页面来承载我们的登陆相关操作。就假定为 camera2
- <!--pages/Camera/verifyphoto.wxml-->
- <!-- verifyphoto.wxml相 -->
- <camera device-position="front" flash="off" binderror="error" class="camera"></camera>
- <!-- 拍照按钮 -->
- <button type="primary" bindtap="takePhoto"> 识别 </button>
- Page({
- data: {
- src:\'\',
- base64: "",
- baidutoken: "",
- msg: null
- },
- //拍照并编码
- takePhoto() {
- var that=this;
- //拍照
- const ctx = wx.createCameraContext()
- ctx.takePhoto({
- quality: \'high\',
- success: (res) => {
- that.setData({
- src: res.tempImagePath
- })
- //图片base64编码
- wx.getFileSystemManager().readFile({
- filePath: that.data.src, //选择图片返回的相对路径
- encoding: \'base64\', //编码格式
- success: res => { //成功的回调
- that.setData({
- base64: res.data
- })
- that.checkPhoto();
- }
- })
- }
- })
- wx.showToast({
- title: \'请重试\',
- icon: \'loading\',
- duration: 500
- })
- },
- error(e) {
- console.log(e.detail)
- },
- checkPhoto: function () {
- var that=this;
- //acess_token获取
- wx.request({
- url: \'https://aip.baidubce.com/oauth/2.0/token\', //真实的接口地址
- data: {
- grant_type: \'client_credentials\',
- client_id: \'xx\',
- client_secret: \'xx\'//用自己的
- },
- header: {
- \'Content-Type\': \'application/json\' // 默认值
- },
- success(res) {
- that.setData({
- baidutoken: res.data.access_token//获取到token
- })
- that.validPhoto();
- }
- })
- },
- validPhoto:function(){
- var that = this;
- //上传人脸进行 比对
- wx.request({
- url: \'https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=\' + that.data.baidutoken,
- method: \'POST\',
- data: {
- image: this.data.base64,
- image_type: \'BASE64\',
- group_id_list: \'tingdemo\',//自己建的用户组id
- },
- header: {
- \'Content-Type\': \'application/json\' // 默认值
- },
- success(res) {
- that.setData({
- msg: res.data.result.user_list[0].score
- })
- if (that.data.msg > 80) {
- wx.showToast({
- title: \'验证通过\',
- icon: \'success\',
- duration: 1000
- }) //验证通过,跳转至UI页面
- wx.switchTab({
- url: \'../UI/ui\',
- })
- }
- }
- });
- }
- })
至此,我们的登陆也搞定了。
实际用到的样式
- .Top {
- position: absolute;
- top: 0rpx;
- width: 100%;
- bottom: 100rpx;
- }
- .csscamera {
- margin: 50rpx 5% 0 5%;
- padding: 5%;
- height: 70%;
- width: 80%;
- border: dashed 1rpx rgb(185, 185, 189);
- }
- .sumbit {
- position: absolute;
- bottom: 0rpx;
- height: 100rpx;
- width: 100%;
- }
- <view class="Top">
- <camera device-position="front" flash="off" binderror="error" class="csscamera"></camera>
- <!-- 拍照按钮 -->
- <button type="primary" bindtap="takePhoto" class="sumbit"> 识别 </button>
- </view>