Face AI

tags: GSS Microsoft Face AI Face Azure AI

Source

https://docs.microsoft.com/zh-tw/azure/cognitive-services/face

Face API Document

Sample API in Postman

Guide

What is Face API

Face Api 主要分為兩大服務

  1. Face Detection - 用來識別圖片裡面的人臉的位置以及人臉的一些相關信息,例如年紀、性別、情緒
  2. Face Recognition
    • Verify - 用來驗證兩個圖片的人臉是不是同一個人
    • Find Similar - 從一堆圖片裡面找出和這個圖片人臉有關的圖片
    • Group - 把一堆圖片的人臉做分類
    • Identity - 判別圖片的人臉是誰

名詞釐清

  1. Face ID: 照片中取出臉部特徵的 ID(一張臉),將在 24hr 被刪除
    • 可以加到 FaceList
  2. Person Group: 一群人的合集(ex: My Friends)
  3. Person: 一個人(某個 Group 中的人,對應到好幾張照片)
  4. Model: 建好 Person Group、Person、Add Face 之後,需要訓練(train) 這個 Group 才能夠用來識別
  1. 在 2019/03 之後,recognitionModel 多了 recognition_02 參數可以選,準確性提高很多
  2. 在 2019/05 之後,Detect(create Face ID) 時,detectionModel 多了 detection_02 可以選,增加圖片人臉辨識能力(增加非常多),但是將無法使用某些參數(Face attributes、landmarks)

Verify vs Identify

  • Verify: 比較兩張照片或是某張照片是否和某個人相同
  • Identify: 找出某張臉的主人

Use Group

  1. 建立 Person Group
  2. 建立 Person
  3. 把人臉加入到 Person
  4. 訓練 Person Group 產生 Model

回傳值

Face Detect

回傳照片裡面所有能辨識到的人臉(max: 100)

  1. 在辨識時須注意 detectionModel 01、02 辨識效果差很多(但 02 無法回傳特徵屬性,若不需要知道年齡、性別、情緒則沒差)
  2. recognitionModel 要與後續識別之群組相同
[ { "faceId": "49f88acc-889a-4432-9ea4-a3a2f4d82694", "faceRectangle": { "top": 73, "left": 201, "width": 67, "height": 67 }, "faceAttributes": { "smile": 0, "gender": "male", "age": 40, "glasses": "ReadingGlasses", "emotion": { "anger": 0, "contempt": 0, "disgust": 0, "fear": 0, "happiness": 0, "neutral": 0.998, "sadness": 0.002, "surprise": 0 } } }, { "faceId": "80e3b477-836c-4321-8a64-f8d380b1e841", "faceRectangle": { "top": 120, "left": 355, "width": 59, "height": 59 }, "faceAttributes": { "smile": 0.776, "gender": "female", "age": 31, "glasses": "NoGlasses", "emotion": { "anger": 0, "contempt": 0.006, "disgust": 0, "fear": 0, "happiness": 0.776, "neutral": 0.214, "sadness": 0.004, "surprise": 0 } } } ]

Get Person Group List

取得所有建立的群組

[ { "recognitionModel": "recognition_02", "personGroupId": "gss", "name": "test", "userData": null } ]

Get Person List

取得所有建立的 Person

[ { "personId": "bb7e0f03-c116-490e-abc2-fa4bd833f394", "persistedFaceIds": [ "91949ee9-3174-4959-8e4a-437b92544341", "fd9c5d78-0756-4b9f-a796-cda4e4861eb4" ], "name": "ChiMi", "userData": null } ]

Identity

人臉識別,request 一次要辨識的人臉(FaceID)最多只能10張

request

{ "personGroupId": "gss", "faceIds": [ "49f88acc-889a-4432-9ea4-a3a2f4d82694", "80e3b477-836c-4321-8a64-f8d380b1e841", "ade7f4db-2f14-499d-b9af-4f8c8e7b041c", "8c7d0ca0-ae68-415c-b396-5d58a15250ac" ], "maxNumOfCandidatesReturned": 10, "confidenceThreshold": 0.5 }

response 結果可設定信心指數多少才會回傳,以及回傳信心指數內識別出的人數(1~100個)

response

[ { "faceId": "49f88acc-889a-4432-9ea4-a3a2f4d82694", "candidates": [ { "personId": "bb7e0f03-c116-490e-abc2-fa4bd833f394", "confidence": 0.90634 } ] }, { "faceId": "80e3b477-836c-4321-8a64-f8d380b1e841", "candidates": [] }, { "faceId": "ade7f4db-2f14-499d-b9af-4f8c8e7b041c", "candidates": [] }, { "faceId": "8c7d0ca0-ae68-415c-b396-5d58a15250ac", "candidates": [] } ]

Webcam

Repo

架構圖

  1. Person 的 Table 需要把 PersonId 改成員工編號(EmpId),因為一個人在多個群組的 PersonId 不一樣,故其對應的人所屬群組也需要增加員工編號。
  2. Person Photo 的 Table 也需要把 PersonId 改為員工編號。

流程

  1. Webcam 截圖(使用 OpenCV)
  2. 避免浪費 API 資源,local 端先辨識人臉(Face-api.js)
  3. 辨識出的影格(Frame)傳 Azure AI 識別
    • 識別一次只能帶上 10 張臉,如果超過需要分好幾次 request 來識別
  4. 收到結果後傳給 Server
  5. 前端顯示識別到的人的資料(照片、姓名etc)

問題

Q1: 在即時辨識下,就算設定截圖的時間間隔,若遇到人物在畫面中定點,該如何避免大量傳送照片?

local 在偵測到人臉時,透過相似度比對一定時間內(ex: 3min)是否有相似的人臉,有則不送 Azure AI。

但是 Face-api.js 的相似度比對需要一張臉比對一張臉

  • 截圖時需要把辨識到的人臉切出來暫存,好用來比對相似度

採用此方法,辨識流程若改:

  1. local 暫存所有切出來的臉
  2. 若該次截圖中發現在暫存中有找到類似的人臉,則採一次辨識一張臉(Azure AI),只辨識新臉孔
  3. 承 (2),若否,則直接傳送截圖,同時辨識多張臉

此方法不可行

  1. 雖然減少相同人臉的辨識次數,以及解決相同的人長時間在畫面中,但不確定是否反而增加辨識的 API 消耗次數
  2. 若使用這種區間暫存的概念,會無法即時得知畫面中的人物離開的訊息,只能知道 ex: 3分鐘內,此畫面有誰曾經出現過,但無法在他離開畫面後短時間內得知,只能等暫存 3 分鐘後清空,才能夠比對得知

若是即時偵測(ex: 3秒偵測一次),則可以知道短時間內的變化,但是有人物定點時,將會以最小間隔(3秒)使用 Azure API

註: 免費額度一分鐘最多使用 20 次 => 3 秒一次

Q2: 免費額度(30000/month)大約可以怎麼用?

((一個月-周末)*上班時間)/30000

((30 - 8) * 10 * 60 * 60) / 30000 ~= 26(per/sec)

識別之前還需要先辨識,故只能將近一分鐘識別一次

Try

測試 Face-api.js 中距離人臉辨識效果

大約 4.5m,辨識效果良好(兩人同時入鏡也有辨識到)

找個幾張照片建立人物

[ { "personId": "67d780eb-d6ab-420b-ba9b-bfebb987afbc", "persistedFaceIds": [ "be59b67a-0299-40a2-9802-49d053fc6e47" ], "name": "Mom", "userData": null }, { "personId": "69de7d4c-c272-48b0-a962-f477be319530", "persistedFaceIds": [ "c6eb9c7a-5143-457d-8cde-e3f188a33cf7", "c8209f39-dcd2-4b66-8cdc-63580ee110b2", "dd8b6f29-2370-41e4-a043-439e6ec678e8" ], "name": "Ryan", "userData": null }, { "personId": "bb7e0f03-c116-490e-abc2-fa4bd833f394", "persistedFaceIds": [ "20a9f74d-22fb-4b1c-9690-41484b1377da" ], "name": "ChiMi", "userData": null } ]

識別的照片

{ "personGroupId": "gss", "faceIds": [ "49f88acc-889a-4432-9ea4-a3a2f4d82694", /* ChiMi */ "50387dc6-a40a-4fcf-adfe-985587391bf0", /* Ryan(上方辨識的照片) */ "ce09139a-a469-4a96-87fe-b63a18057aa8" /* Mom(上方辨識的照片) */ ], "maxNumOfCandidatesReturned": 10, "confidenceThreshold": 0.5 }

識別結果

[ { "faceId": "49f88acc-889a-4432-9ea4-a3a2f4d82694", "candidates": [ { /* ChiMi */ "personId": "bb7e0f03-c116-490e-abc2-fa4bd833f394", "confidence": 0.90469 } ] }, { "faceId": "50387dc6-a40a-4fcf-adfe-985587391bf0", "candidates": [ { /* Ryan */ "personId": "69de7d4c-c272-48b0-a962-f477be319530", "confidence": 0.65972 } ] }, { "faceId": "ce09139a-a469-4a96-87fe-b63a18057aa8", "candidates": [ { /* Mom */ "personId": "67d780eb-d6ab-420b-ba9b-bfebb987afbc", "confidence": 0.827 } ] } ]
  1. ChiMi 訓練的照片&識別的照片都是網路找解析度還不錯,故識別信心度達 0.9
  2. Ryan 的辨識效果不好,陸續加了三張清楚的臉部照片訓練,最後才達到 0.65
  3. Mom 的訓練照片只有一張臉部照片,但識別出來的信心度卻有達到 0.82
  • 檢討: Ryan 識別信心度太低應該是識別的照片頭髮太長太厚