Face AI
===
###### tags: `GSS` `Microsoft` `Face AI` `Face` `Azure AI`
[TOC]
## Source
https://docs.microsoft.com/zh-tw/azure/cognitive-services/face
[Face API Document](https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d)
[Sample API in Postman](https://drive.google.com/open?id=1bgl9ZEAsTAyef5soGE8T4WjtRz4EtAR9)
## Guide
### What is Face API
Face Api 主要分為兩大服務
1. Face Detection - 用來識別圖片裡面的人臉的位置以及人臉的一些相關信息,例如年紀、性別、情緒...
2. Face Recognition
- Verify - 用來驗證兩個圖片的人臉是不是同一個人
- Find Similar - 從一堆圖片裡面找出和這個圖片人臉有關的圖片
- Group - 把一堆圖片的人臉做分類
- Identity - 判別圖片的人臉是誰
:::info
名詞釐清
1. Face ID: 照片中取出臉部特徵的 ID(一張臉),將在 24hr 被刪除
- 可以加到 FaceList
2. Person Group: 一群人的合集(ex: My Friends)
3. Person: 一個人(某個 Group 中的人,對應到好幾張照片)
4. Model: 建好 Person Group、Person、Add Face 之後,需要訓練(train) 這個 Group 才能夠用來識別
:::
:::success
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)
:::info
1. 在辨識時須注意 **detectionModel** 01、02 辨識效果差很多(但 02 無法回傳特徵屬性,若不需要知道年齡、性別、情緒...則沒差)
2. **recognitionModel** 要與後續識別之群組相同
:::
```json=
[
{
"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
取得所有建立的群組
```json=
[
{
"recognitionModel": "recognition_02",
"personGroupId": "gss",
"name": "test",
"userData": null
}
]
```
#### Get Person List
取得所有建立的 Person
```json=
[
{
"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**
```json=
{
"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**
```json=
[
{
"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](https://github.com/hbdoy/face-AI)
### 架構圖
![](https://i.imgur.com/FT1qrOt.png)
![](https://i.imgur.com/7Ri7BuE.jpg)
:::danger
1. Person 的 Table 需要把 PersonId 改成員工編號(EmpId),因為一個人在多個群組的 PersonId 不一樣,故其對應的**人所屬群組**也需要增加員工編號。
2. Person Photo 的 Table 也需要把 PersonId 改為員工編號。
:::
![](https://i.imgur.com/QsSbrWJ.jpg)
### 流程
1. Webcam 截圖(使用 OpenCV)
2. 避免浪費 API 資源,local 端先辨識人臉(Face-api.js)
3. 辨識出的影格(Frame)傳 Azure AI 識別
- 識別一次只能帶上 10 張臉,如果超過需要分好幾次 request 來識別
4. 收到[結果](####Identity)後傳給 Server
5. 前端顯示識別到的人的資料(照片、姓名...etc)
### 問題
#### Q1: 在即時辨識下,就算設定截圖的時間間隔,若遇到人物在畫面中定點,該如何避免大量傳送照片?
local 在偵測到人臉時,透過相似度比對一定時間內(ex: 3min)是否有相似的人臉,有則不送 Azure AI。
但是 Face-api.js 的相似度比對需要一張臉比對一張臉
- 截圖時需要把辨識到的人臉切出來暫存,好用來比對相似度
採用此方法,辨識流程若改:
1. local 暫存所有切出來的臉
2. 若該次截圖中發現在暫存中有找到類似的人臉,則採一次辨識一張臉(Azure AI),只辨識新臉孔
3. 承 (2),若否,則直接傳送截圖,同時辨識多張臉
:::danger
此方法不可行
1. 雖然減少相同人臉的辨識次數,以及解決相同的人長時間在畫面中,但不確定是否反而增加辨識的 API 消耗次數
2. 若使用這種區間暫存的概念,會無法即時得知畫面中的人物離開的訊息,只能知道 ex: 3分鐘內,此畫面有誰曾經出現過,但無法在他離開畫面後短時間內得知,只能等暫存 3 分鐘後清空,才能夠比對得知
:::
:::info
若是即時偵測(ex: 3秒偵測一次),則可以知道短時間內的變化,但是有人物定點時,將會以最小間隔(3秒)使用 Azure API
:::
:::warning
註: 免費額度一分鐘最多使用 20 次 => 3 秒一次
:::
#### Q2: 免費額度(30000/month)大約可以怎麼用?
((一個月-周末)*上班時間)/30000
((30 - 8) * 10 * 60 * 60) / 30000 ~= 26(per/sec)
識別之前還需要先辨識,故只能將近一分鐘識別一次
### Try
測試 Face-api.js 中距離人臉辨識效果
大約 4.5m,辨識效果良好(兩人同時入鏡也有辨識到)
![](https://i.imgur.com/aZeDeC6.jpg)
![](https://i.imgur.com/b36uVSs.jpg)
找個幾張照片建立人物
```json=
[
{
"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
}
]
```
識別的照片
```json=
{
"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
}
```
識別結果
```json=
[
{
"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
}
]
}
]
```
:::info
1. ChiMi 訓練的照片&識別的照片都是網路找解析度還不錯,故識別信心度達 0.9
2. Ryan 的辨識效果不好,陸續加了三張清楚的臉部照片訓練,最後才達到 0.65
3. Mom 的訓練照片只有一張臉部照片,但識別出來的信心度卻有達到 0.82
- 檢討: Ryan 識別信心度太低應該是識別的照片頭髮太長太厚
:::