如何實現基於微信小程序的人臉識別

現在關於人臉識別的SDK其實有很多,諸如face++、百度大腦之類的,他們都能爲開發者免費提供人臉識別的接口。阿里也和face++合作,實現了支付寶的刷臉支付。

但是很遺憾,網上關於識別一段視頻中的用戶行爲(諸如搖搖頭,眨眨眼,微笑)的資料很少,可能是技術沒有公開,所以只能自己去想解決方法了。本人最近在做一個關於微信小程序的畢業設計,所以想到了把這兩個技術結合下,這裏寫篇博客,爲大家解解惑吧,純是自己的一些想法,如果大家有疑惑或者更好的建議,可以發郵件聯繫我([email protected])。


大致的解決方案如下
這裏寫圖片描述

圖可能不是很清晰,請看這裏

  1. 用戶在微信小程序中拍攝一段視頻
  2. 將用戶拍攝的視頻傳到七牛雲服務器
  3. 藉助七牛雲服務器的媒體處理api對視頻每隔一定時間截圖,形成一張張視頻切圖
  4. 使用百度大腦的人臉識別api分析每張圖中用戶的行爲,最後得出結論

現在開始coding:

A. 先初始化一個微信小程序的項目,然後新建一個video頁面,這個頁面的js中需要首先引入七牛雲上傳文件的js—qiniuUpload.js,然後綁定拍攝視頻的按鈕的事件—chooseVideo,代碼大致如下:

chooseVideo: function () {
    initQiniu();
    var that = this;
    wx.chooseVideo({
      sourceType: ['camera', 'album'],
      camera: 'front',
      maxDuration: 40,
      success: function (res) {
        console.log('拍照之後:');
        console.log(res);
        that.setData({
          src: res.tempFilePath
        });
        //七牛上傳文件
        var vedioObject = res;
        var filePath = res.tempFilePath;
     },error: function(err){
       console.log(err)
     }
   }  

這樣就把用戶在拍攝之後的視頻信息(時長,高度,寬度,臨時存儲地址拿到了),接下來就是上傳到七牛雲服務器了。

B. 將視頻上傳到七牛雲服務器
上傳文件到七牛過程呢,有一點小複雜,建議大家先去看下七牛的官方技術文檔,這裏後臺我是用的是php,但是實際上七牛的SDK幾乎支持所有的主流語言,所以對php不熟悉的同學也不用太擔心。
大致的流程就是先搭建一個獲取上傳token的接口,在上傳文件的時候你需要首先請求這個接口,獲得的token是作爲上傳函數的必要參數,這是使用七牛PHP SDK的代碼:

<?php
  require '../qiniu-sdk/autoload.php';
  use Qiniu\Auth;
  // 用於簽名的公鑰和私鑰
  $accessKey = 't5tBss9FrousfymdmFw4ki2fscwZ8qGaIw8SZmX8';
  $secretKey = 'uASYB6XxzJy9tLWeGsLaNaQyX4bVafIVh6Dpgvxo';
  // 初始化籤權對象
  $auth = new Auth($accessKey, $secretKey);

  // 空間名  https://developer.qiniu.io/kodo/manual/concepts
  $bucket = 'andyliwr-server';
  // 生成上傳Token
  $upToken = $auth->uploadToken($bucket);
  $returnData = array('uptoken'=>$upToken);
  echo json_encode($returnData);

然後就是在微信小程序中調用七牛的上傳api,這裏感謝未知名大神的源碼貢獻,建議好好看看README,裏面的qiniuUpload.js已經幫我們封裝好了,直接設置定義參數,然後調用initQiniu(),就可以使用qiniuUploader.upload的上傳函數,需要設定的參數如下:

var options = {
    region: 'SCN', // 華東區,生產環境應換成自己七牛帳戶bucket的區域
    uptokenURL: 'https://xxxxx/uploadImg.php', // 生產環境該地址應換成自己七牛帳戶的token地址,具體配置請見server端
    domain: 'https://xxxxx/' // 生產環境該地址應換成自己七牛帳戶對象存儲的域名
  };

大致過程如下
- 從 github 上下載qiniuUploader.js,導入小程序工程。

  • 在使用 SDK 之前,您必須先註冊一個七牛雲帳號,並登錄控制檯獲取一對有效的 AccessKey 和 SecretKey,您可以閱讀 如何接入七牛 安全機制 以進一步瞭解如何正確使用和管理密鑰 。

  • SDK 依賴服務端頒發 uptoken,可以通過以下二種方式實現:

  • 您需要了解您的七牛存儲空間設置在那個區域,比如華東,華南等,參見區域設置

後端服務應提供一個 URL 地址,供小程序請求該地址後獲得 uptoken。請求成功後,服務端應返回如下格式的 json(至少包含 uptoken 字段):

{
    "uptoken": "0MLvWPnyya1WtPnXFy9KLyGHyFPNdZceomL..."
}

根據你創建的七牛存儲空間,把對應的 https 上傳地址添加到小程序的訪問白名單中,方法如下:

  1. 登錄 微信公衆平臺,前往 設置 - 開發設置,點擊 服務器配置 下的「修改」鏈接。
  2. 修改 uploadFile 域名(比如華北 https 上傳地址爲:https://up-z1.qbox.me,地址不清楚請參見https地址附錄)
  3. 如果需要下載文件,則還需要一同設置 downloadFile 域名,爲你的 bucket 下載地址
  4. 保存即可
字段名 內容
request 域名 https://yourServce.com
uploadFile 域名 https://up.qbox.me (根據存儲區域填寫)
downloadFile 域名 https://baldkf.bkt.clouddn.com

存儲區域對應 HTTPS 地址,參考官方文檔

存儲區域 區域代碼 HTTPS 地址
華東 ECN https://up.qbox.me
華北 NCN https://up-z1.qbox.me
華南 SCN https://up-z2.qbox.me
北美 NA https://up-na0.qbox.me

配置好參數之後,你就應該可以體驗下看看能否成功上傳視頻了了,ps:我這裏講得比價籠統,不會的直接下再小程序的源碼,開始整。

C. 視頻上傳成功之後,接下就是分解視頻了,這裏有必要說下七牛雲的媒體處理api,就那存在我空間裏的一段視頻來說,我想拿到它在第一秒時的切圖,只需要在視頻地址後面帶上參數?vframe/jpg/offset/1,比如上述視頻的第一秒切圖就是https://olpkwt43d.qnssl.com/girl.mp4?vframe/jpg/offset/1,第二秒就是https://olpkwt43d.qnssl.com/girl.mp4?vframe/jpg/offset/2

所以想要獲取到所有切圖只需要結合視頻時長寫一個循環就好了,另外兩個參數w是視頻的寬度,h是視頻的高度,這些需要微信小程序發送給後臺:

var allPicture = [];
for(var i=0; i<vedioObject.duration; i++){
  allPicture.push(res.imageURL+'?vframe/jpg/offset/'+i+'/w/'+vedioObject.width+'/h/'+vedioObject.height+'/rotate/0');
}
 wx.request({
   url: https://xxxxx/analysis/request/AipFace.php + '?video_url=' + res.imageURL + '&duration=' + vedioObject.duration + '&width=' + vedioObject.width + '&height=' +vedioObject.height, //僅爲示例,並非真實的接口地址
   header: { 'content-type': 'application/json' },
   success: function (res) { ..........

D: 使用百度API做人臉分析
同樣的百度API雖然對個人用戶免費但是需要註冊一個appid,這裏建議去看下百度的文檔,我這裏就不多說了,不會的直接下載代碼

最後對接後返回的結果做個檢測,isSimle爲true則表示用戶微笑了:

var isSimle = res.data.result.some(function(item){
 if(item.result instanceof Array){
   return item.result.some(function(item2){
     return item2.expression == '1';
   })
 }else{
   return item.result.expression == '1';
 }
});

最後,覺得有啥不懂的,你可以聯繫我,踩坑是肯定的,做程序員咱們就得有這覺悟,不懂的你可以聯繫我([email protected]),也可以關注我的github(https://github.com/Andyliwr).

發佈了59 篇原創文章 · 獲贊 80 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章