微信小程序 人臉識別登陸模塊


微信小程序---人臉識別登陸的實現

關鍵詞:微信小程序 人臉識別 百度雲接口

前言

這是一篇關於一個原創微信小程序開發過程的原創文章。涉及到的核心技術是微信小程序開發方法和百度雲人臉識別接口。小程序的主體是一個用於個人密碼存儲的密碼管理器,在登陸注冊階段,需要調用百度雲人臉識別接口以及百度雲在線人臉庫的管理接口。本文主要涉及登陸注冊模塊的實現,而且不需要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="width: 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="width: 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版

打開小程序調試功能:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM