云开发:让你拥有自己的第一个AI人脸识别小程序
文章目錄
- 博主緒論
- 準備過程
- GIT的安裝
- NodeJS和npm的安裝
- 騰訊云人臉識別API
- 正式開始
- 創建云開發小程序
- 開發前的思考準備,思維決定行動
- 服務器開發(寫一個云函數端)
- 分析
- 調用人臉識別API
- 云存儲
- 測試環節
- 服務端代碼完成
- 客戶端開發(真正的小程序前端界面+后端調用)
- 準備階段
- 客戶端提交上傳圖片
- 調用云函數處理fileID,返回臉部信息
- 把得到的人臉數據顯示到前端頁面
- 顯示我們上傳的圖片
- 布局優化
博主緒論
微信小程序云開發可以免費調用云開發控制臺的云存儲,云函數,云計算,當然只是一定程度上可以免費調用。不過這也比較有意思,逼格也高,而且云開發可以讓我們輕易的在小程序當中和用戶進行交互,接下來讓我們緊跟時代潮流,利用圖靈完備打造出鼠于我們的一個AI人臉識別神器吧。
準備過程
在此之前,我們需要安裝幾個東西。
GIT的安裝
進入GIT官網,點擊這,根據自己的電腦系統版本下載,下載完成以后,打開命令行(cmd),輸入命令git,如果成功顯示出一大段我們看不懂的字符,那就對了。
NodeJS和npm的安裝
進入NodeJS官網下載,點擊,下載對應版本即可,下載完成以后,在自己的cmd上面輸入node -v和npm -v即可,如果顯示出版本,就證明安裝成功了。
騰訊云人臉識別API
首先注冊一個自己的騰訊云賬號,點擊進入官網,點擊注冊,注冊完賬號以后,還得實名認證才能夠正常使用,這個過程很快的。
之后我們還得調用騰訊云的人臉識別API接口,我們就得先開通這個服務,點擊產品->人工智能->人臉識別->立即使用即可。之后如果我們向調用騰訊云API的話,我們還得去控制臺->訪問管理創建API密匙,之后會出現APPID,SecretID,SecretKey,之后我們調用API需要使用。
正式開始
創建云開發小程序
創建的時候勾選小程序-云開發即可:
之后小程序會自動生成一個模板,我們看它不爽就全刪了,自己重新創建。把所有文件刪掉(處理project.config.json),重新打開開發工具,然后新建兩個目錄,一個事服務器(命名為server),一個是客戶端(命名為client),建立完目錄以后,再到配置文件project.config.json里面改動一下:就改動這兩行
改動完以后,保存,然后重新打開開發工具,我們可以看見服務器目錄出現了一個云圖標:
這個時候我們的環境就準備好了。但是或許有點人會出現環境未知,不要怕,博主也是,你就點擊:
點擊里面的云開發選項就可以看到提示,教你創建環境。
開發前的思考準備,思維決定行動
功能設想:
-
客戶端選擇或者拍照圖片進行上傳,然后在小程序當中調用云存儲函數上傳到我們個人的云存儲當中,并且云存儲會返回一個文件ID到客戶端。
-
客戶端獲取文件ID,調用云函數,云函數就會讀取這個文件ID,在云存儲當中找到這個文件圖片的位置,并且進行讀取,獲得其真實的URL地址
-
將獲取到的URL發送到騰訊云的人臉識別API,之后人臉識別API會返回圖片的相關信息
-
我們將這些信息一一進行處理,然后發給客戶端,并且進行顯示。
-
優化顯示界面
服務器開發(寫一個云函數端)
首先,我們右鍵選擇server文件夾,然后選擇建立NodeJS云函數,命名為FaceDetect(名字隨意,只要容易辨認就好),建立完成以后,目錄下面會自動生成index.js和package.json文件,其中index.js文件里面有官方給出的模板,我們把多余的代碼刪掉
// 云函數入口文件 const cloud = require('wx-server-sdk') cloud.init() // 云函數入口函數 exports.main = async (event, context) => {}分析
這個我們暫時先放下,我們先去騰訊云,找到人臉識別的開發文檔,點擊這里
之后選擇人臉檢測與分析相關接口,即DetectFace。
在這個文檔我們可以看到很多詳細的信息,比如說面部屬性和人臉質量信息的識別。當然這個部署最重要的,最重要的是我們該怎么用,用哪些。
-
首先我們看到輸入參數:
里面的Action(接口名稱)和Verxion(版本)是必填的,而我們需要識別的圖片是云存儲上傳的圖片,因此需要URL參數,而且我們獲取的是人臉的屬性信息,因此我們還需要參數NeedFaceAttributes. -
再看到輸出參數,里面有:
圖片的寬高,人臉信息列表(最重要的),因此我們點擊FaceInfo
里面有:
其中我們會用到FaceAttributesInfo即人臉屬性信息,然后點擊FaceAttributesInfo查看詳細信息,發現里面有很多人臉信息輸出,比如說頭發信息,咦,頭發信息還有一個文檔可以點擊,有什么呢,我們看看:FaceHairAttributesInfo
里面有頭發的顏色,程度,劉海,信息看來十分具體。
以上是人臉識別API的參數分析,我們了解參數分析以后,后面的執行步驟才不會那么的懵逼。
調用人臉識別API
進入這一頁,我們可以看到相關的SDK,SDK用起來有些許麻煩,我們可以常常新鮮東西,API Explorer,即SDK版本的GUI界面,調用API十分方便:
點擊API Explorer我們可以進入到以下頁面:
里面有我們前面說到的SecretId和SecretKey,還有我們前面的輸入參數URL和NeedFaceAttributes(人臉屬性列表),我們把這些內容給填寫了,其他的不管,URL我們可以隨便從網上找一張人臉圖片的地址,填入,然后后面那個Need什么的參數就填寫1就OK了,之后我們點擊右側的在線調用進行測試,看我們的接口調用成功沒,然后選擇發送請求,會出現以下結果:
如果你出現了以下類似的結構,人臉信息,那么就對了,如果出現錯誤,那么就是你的人臉檢測服務沒啟用或者沒有實名認證,去上面看看吧。
之后選擇代碼生成,選擇NodeJS,此時我們就當一個搬運工,把這里的代碼復制即可:
接下來我們把復制的代碼加到我們云函數的index.js上面(稍微做點改動):
記住,把第二行代碼多余的那些點點杠杠給刪了,因為我們將會使用npm install的方式安裝這幾個依賴包。
右鍵選擇云函數FaceDetect,然后選擇使用終端打開,輸入下面兩行命令:
很詭異的是,在你輸入第一個命令的時候,安裝成功了,但是輸入第二個命令的時候卻見鬼了,不管輸入幾次,都會報錯:
npm ERR! Unexpected end of JSON input while parsing near '...-/buffer-2.1.11.tgz"}'npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\23521\AppData\Roaming\npm-cache\_logs\2020-02-04T07_54_43_051Z-debug.log遇到這個錯誤不要怕,因為博主也為例這個bug花了很長的時間才解決,后面才發現,我們需要首先清理緩存,輸入以下命令:
npm cache clean --force之后我們把下載改為鏡像下載(不是淘寶鏡像哦),輸入以下命令:
npm set registry https://registry.npmjs.org/輸入完上面那行命令以后,系統還會繼續讓你輸入,此時已經改為鏡像下載,你可以輸入你的第二行下載命令了:
npm install wx-server-sdk --save好!現在總算下載完了,下載完以后,你可別著急,測試一下看看,我們下載的東西是不是真的有用,在當前終端中輸入node index.js.
如果出現了一些人臉的信息,那么就是下載成功了。依賴包下載這部總算圓滿完成了。
云存儲
現在我們進入到云存儲環節,打開之前開發工具的云開發按鈕,我們就可以看到云開發控制臺,之后進入存儲管理界面:
之后我們隨便上傳一張圖片(前提是我們小程序image目錄里面的,如果沒有,可以建一個專門存放圖片),上傳以后,會出現一個文件的ID,復制一下。
接下來我們可以看到微信小程序開發的云存儲文檔,點擊這里,我們在這里面可以看到一個函數,可以專門把云存儲當中文件對應的ID轉換成真實的URL地址,我們每個人都可以調用。我們可以看到這樣的代碼:
這個時候咱們應該毫不猶豫的把它復制粘貼搬磚搬過來給我們用。
但是呢我們需要把第三行代碼當中的cloud://xxx改成我們上面的文件ID ,我們可以把這幾行代碼放入到我們云函數的index.js文件當中的主函數:
測試環節
我們干完上面的操作以后,可以緩一口氣了,右鍵選擇我們的云函數FaceDetect,然后選擇上次并部署所有文件,等待上傳成功以后,我們可以在云開發控制臺那選擇云函數,并且選擇云端測試按鈕,進行相應的測試,看看我們的云函數是不是可以正常調用,輸出結果是不是對的:
之后點擊運行測試,如果運行結果當中順利的出現了fileID和其對應的tempFileURL,就說明云函數部署成功,測試成功。
服務端代碼完成
經過上述測試成功以后,我們進行代碼整合:
const cloud = require('wx-server-sdk') //小程序云開發SDK const tencentcloud = require("tencentcloud-sdk-nodejs"); //騰訊云API 3.0 SDK cloud.init() //云開發初始化 var synDetectFace = function(url) { //人臉識別APIconst IaiClient = tencentcloud.iai.v20180301.Client; //API版本const models = tencentcloud.iai.v20180301.Models; //API版本const Credential = tencentcloud.common.Credential;const ClientProfile = tencentcloud.common.ClientProfile;const HttpProfile = tencentcloud.common.HttpProfile;let cred = new Credential("你的SecretID", "SecretKey"); //騰訊云的SecretId和SecretKeylet httpProfile = new HttpProfile();httpProfile.endpoint = "iai.tencentcloudapi.com"; //騰訊云人臉識別API接口let clientProfile = new ClientProfile();clientProfile.httpProfile = httpProfile;let client = new IaiClient(cred, "", clientProfile); //調用就近地域let req = new models.DetectFaceRequest();let params = '{"Url":"' + url + '","NeedFaceAttributes":1}' //拼接參數,由于人臉識別圖片的URL會變化,所有URL采用變量req.from_json_string(params);return new Promise(function(resolve, reject) { //構造異步函數,把人臉識別內容返回client.DetectFace(req, function(errMsg, response) {if (errMsg) {reject(errMsg)} else {resolve(response);}})}) }exports.main = async(event, context) => {const data = event //在客戶端調用云函數的時候返回的數據const fileList = [data.fileID] //讀取來自客戶端的fileIDconst result = await cloud.getTempFileURL({fileList, //向云存儲發起讀取文件臨時地址請求})const url = result.fileList[0].tempFileURL //一次次調用,fileList里面只有一個data.fileID,因此只需要fileList[0]datas = await synDetectFace(url) //調用異步函數,向騰訊云API發起請求return datas }服務端代碼完成以后,我們上傳到云函數,右鍵選擇云函數,選擇上次并部署所有文件,更新云函數。
客戶端開發(真正的小程序前端界面+后端調用)
準備階段
右鍵選擇client文件目錄(存放各種頁面的目錄),然后新建一個app.json文件,app.js文件(這些是頁面目錄必須的文件),選擇app.json文件,在里面加入代碼:
{"pages": ["pages/index/index"],"window": {"navigationBarBackgroundColor": "#333366","navigationBarTextStyle": "black","navigationBarTitleText": "容顏下的密碼","backgroundColor": "#eeeeee","backgroundTextStyle": "light","enablePullDownRefresh": false},"cloud": true,"sitemapLocation": "sitemap0.json" }保存文件,就會自動生成相關目錄和文件,當然,如果沒有生成,也別著急,你可以嘗試把pages/index/index重新自己寫一遍,然后保存,就可以出來了。
客戶端提交上傳圖片
對于這個功能實現,我們需要在client下面生成的index.js文件里面寫入一個相關的功能函數,并且于相關的上傳按鈕綁定起來即可。對于上傳圖片功能,開發文檔里面講的比較清楚,博主就負責整合這個資源給大家使用,點擊這里進入,我們可以看到里面有各種參數,其中屬性我們可以相應的選擇好,當選擇完圖片以后,會把相應的輸出結果放入到res當中,我們從res當中得到tempFilePaths,即當前上傳圖片的圖片的本地臨時文件路徑列表 (本地路徑),代碼如下:
UploadImage(){wx.chooseImage({count: 1,sizeType: ['original', 'compressed'],sourceType: ['album', 'camera'],success(res) {const tempFilePaths = res.tempFilePathsconsole.log(tempFilePaths)}})},當我們得到這個當前需要上傳的文件臨時存儲路徑以后,我們可以把它上傳到云存儲上面,得到對應的fileID,然后我們通過對應的函數得到URL,再調用云函數得到臉部信息即可,具體上傳云存儲的函數可以參考這里,根據這個文檔提供的函數我們可以修改代碼,在上傳文件成功以后,獲得相應的臨時路徑,然后調用這個路徑,上傳到云存儲當中,加入隨機數,生成隨機的云路徑,以便于更多的用戶上傳:
UploadImage:function(){var random = Date.parse(new Date())+Math.ceil(Math.random()*1000) //設置云存儲路徑的隨機數,以便于多個用戶使用時生成多個路徑 wx.chooseImage({count: 1,sizeType: ['original', 'compressed'],sourceType: ['album', 'camera'],success(res) {const tempFilePaths = res.tempFilePaths[0] //保存當前生成的臨時路徑console.log(tempFilePaths)wx.cloud.uploadFile({cloudPath: random+'.jpg', //云存儲路徑filePath: tempFilePaths, // 文件路徑success: res => { //成功則回調console.log(res.fileID) //生成對應的fileID},})}})},當然,在進入小程序調用云函數之前,我們必須得有一個初始化的環節,即在加載頁面的時候,對云環境進行初始化:
/*** 生命周期函數--監聽頁面加載*/onLoad: function (options) {wx.cloud.init({env: 'test-ws9kn' //初始化的環境ID,之前建立云環境的時候的ID})},接下來我們可以進行一個小小的測試,運行小程序,選擇圖片,如果上傳成功以后,控制臺打印出了文件的fileID,那么就證明測試成功。
調用云函數處理fileID,返回臉部信息
具體可以參考微信開發者文檔當中云函數,我們需要的參數有:name(調用的云函數的名字),data(云函數需要的參數,即fileID),因此在上傳云存儲成功以后,我們再調用云函數處理對應的fileID,得到我們需要的臉部信息,加入相應的代碼,其它不變:
wx.cloud.uploadFile({cloudPath: random+'.jpg',filePath: tempFilePaths, // 文件路徑success: res => {console.log(res.fileID)wx.cloud.callFunction({name: 'Face_Detection',data: {fileID:res.fileID},success: res => {console.log(res.result)},})},我們繼續進行小小的測試,運行小程序,上傳我們需要進行人臉識別的圖片,然后觀察控制臺,如果打印出了對應的人臉信息,那么測試成功。
把得到的人臉數據顯示到前端頁面
根據上面輸出的人臉信息,我們可以看到很多類型的人臉信息,我們具體可以看看騰訊云文檔的內容
假設我們需要去看的參數有年齡,是否戴眼鏡,是否戴帽子,是否戴口罩,性別,頭發長度,是否有劉海,頭發顏色等等。此時可以在WXML文件當中加入相應的組件:
當然此時前端界面能夠看到的參數只有一些具體的數字或者true,false等等,為了更加人性化的設計,我們可以進行相應的改進,比如說gender小于50 的時候,性別為女,再比如說hair_length結果輸出為0的時候我們可以把輸出改為光頭顯示在界面上等等,具體改法,可以參考文檔,可以利用if語句,switch語句進行改寫:
//。。。。。上面代碼不變,就在云函數調用成功以后,把信息顯示在界面上,當然為了能夠把信息顯示在界面上就得調用setData函數,但是this不能使用,首先得在UploadImage函數開始的時候寫入代碼:var that = this 把this給that。 wx.cloud.callFunction({name: 'Face_Detection',data: {fileID:res.fileID},success: res => {that.setData({age: res.result.FaceInfos[0].FaceAttributesInfo.Age,glasses: res.result.FaceInfos[0].FaceAttributesInfo.Glass,beauty: res.result.FaceInfos[0].FaceAttributesInfo.Beauty,mask: res.result.FaceInfos[0].FaceAttributesInfo.Mask,hat: res.result.FaceInfos[0].FaceAttributesInfo.Hat,})if (res.result.FaceInfos[0].FaceAttributesInfo.Gender < 50) {myThis.setData({gender: "女"});} else {myThis.setData({gender: "男"});}switch (res.result.FaceInfos[0].FaceAttributesInfo.Hair.Length) {case 0:myThis.setData({hair_length: "光頭"});break;case 1:myThis.setData({hair_length: "短發"});break;case 2:myThis.setData({hair_length: "中發"});break;case 3:myThis.setData({hair_length: "長發"});break;case 4:myThis.setData({hair_length: "綁發"});break;}switch (res.result.FaceInfos[0].FaceAttributesInfo.Hair.Bang) {case 0:myThis.setData({hair_bang: "有劉海"});break;case 1:myThis.setData({hair_bang: "無劉海"});break;}switch (res.result.FaceInfos[0].FaceAttributesInfo.Hair.Color) {case 0:myThis.setData({hair_color: "黑色"});break;case 1:myThis.setData({hair_color: "金色"});break;case 3:myThis.setData({hair_color: "棕色"});break;case 4:myThis.setData({hair_color: "灰白色"});break;}},})},})}})},對應的如果前端頁面的各種值需要隨著函數而改變,就必須定義變量,需要在data當中聲明這些變量:
/*** 頁面的初始數據*/data: {Beauty: '請上傳照片',age: '請上傳照片',glasses: '請上傳照片',mask: '請上傳照片',hat: '請上傳照片',gender: '請上傳照片',hair_length: '請上傳照片',hair_bang: '請上傳照片',hair_color: '請上傳照片',顯示我們上傳的圖片
首先得在前端加上圖片組件,而圖片會隨著上傳的圖片而改變,因此圖片地址src也需要變量處理:
<view class="image_view"> <image src="{{image_src}}" style="width:200px;height:200px;"></image> </view>并且把這個變量加入到data當中。
我們可以在上傳函數執行成功,即上傳圖片,生成臨時路徑成功的時候,把臨時路徑賦值給這個地址變量:
之后就可以顯示出我們上傳的圖片了。
布局優化
打開我們WXSS文件,根據我們的設計需要,設計相關的布局:
.info_view{padding-left: 20px;padding-top: 10px;padding-right: 20px;padding-bottom: 20px; } .info{display: flex;flex-direction: column;color: blue; } .image_view{display: flex;justify-content: center;background: blanchedalmond } .button_view{display: flex;padding-top: 20px;padding-bottom: 20px; } .button_size{width: 200px;height: 50px;}博主還加了一個進度條(根據上傳進度,時間,加入到上傳進度當中具體參考API,并且這里的代碼中,我們將wx.cloud.uploadFile存為名為uploadTask的變量,然后在最后調用onProgressUpdate(res)方法,并通過setData方法,將數據展示在前端
,識別狀態欄(信息讀取成功會在界面上顯示加載成功,識別過程中會顯示消息欄:加載中,具體參考這里)
整個AI人臉識別的小程序樣例大概就出來了,界面可以進行相關的優化,這個大家可以根據自己的需要把界面優化,變得更加漂亮,博主寫了這么久,也寫不下去了,接下來就看大家自己去優化了,有想法就去做。我上面講的也差不多了。這是我上傳圖片后的樣例:
最后,看博主寫了一天的博客了,博主不求什么打賞啥的,博主覺得轉發這篇博客就是對博主最大的饋贈了,最后,祝大家新的一年里,越來越好!!!也歡迎大家關注我的個人博客,在下所有的文章都是從個人博客導入進來的,文章會首先更新在個人博客里。希望我的博客能夠給大家帶來收獲!
與這篇文章一個系列的還有:
微信小程序從入門到入坑
天氣之子
總結
以上是生活随笔為你收集整理的云开发:让你拥有自己的第一个AI人脸识别小程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓桌面壁纸_小米全新MIUI 12正式
- 下一篇: 消防应急照明和疏散指示系统在某医药厂房项