---
# System prepended metadata

title: Face detection in Python (臉部識別)
tags: [Face Engine, face recognition, Face Detection, face landmark, Python]

---

# Face detection in Python (臉部識別)

## Introduction (簡介)

- Face-engine 是一個用於人臉識別和人臉特徵檢測的 Python 套件
- 它利用先進的機器學習算法來檢測和分析人臉屬性。此套件適用於需要生物識別身份驗證、人臉屬性識別和情感檢測的應用。

### face-engine 的功能

1. 人臉檢測：識別並定位圖像中的人臉。
2. 人臉標誌檢測：檢測關鍵的人臉特徵，如眼睛、鼻子和嘴巴。
3. 情感識別：分析面部表情以確定情感。
4. 人臉識別：根據面部特徵識別或驗證個人。
5. 年齡和性別預測：估計圖像中人物的年齡和性別。

## 環境設定 (Windows OS)

### 使用 conda 建立 Workspace 的環境

- face_engine 套件尚未支援 Python 3.11+ 
- 請用 conda 建立一個 Python 版本為 3.10 的環境
:::warning
使用 python 環境管理套件，按 + 號
![Screenshot 2024-05-25 at 11.33.31 AM](https://hackmd.io/_uploads/rJLDhCAmC.png =40%x)
:::

:::danger
選擇 Python 3.10
![Screenshot 2024-05-25 at 11.36.19 AM](https://hackmd.io/_uploads/rk7VpRRXC.png)
:::

:::success
打上此環境的名字，例如 FD_Project
![Screenshot 2024-05-25 at 11.39.43 AM](https://hackmd.io/_uploads/HyFTTR070.png)
:::

:::warning
將剛建立的 FD_Project 設定成開啟專案 (workspace) 自動使用這個環境
![Screenshot 2024-05-25 at 11.49.15 AM](https://hackmd.io/_uploads/SJUfeyyN0.png)
:::

:::info
透過 env 的終端機按鈕啟用終端機
![Screenshot 2024-05-25 at 11.56.53 AM](https://hackmd.io/_uploads/Bycz7114R.jpg)
:::

:::success
使用下列指令查看在環境下的 Python 版本及目前 conda 版本
![Screenshot 2024-05-25 at 12.04.49 PM](https://hackmd.io/_uploads/SkFPVkkER.png)
:::

-----

### 安裝 face-engine 套件
:::warning
使用 `python -m pip install face_engine` 指令安裝 face_engine 套件 
![Screenshot 2024-05-25 at 12.31.12 PM](https://hackmd.io/_uploads/rkQ-51JEA.jpg)
:::

:::info
寫一個簡單的程式先測試 face_engine 是否成功安裝，並且可以引用
![Screenshot 2024-05-25 at 12.39.22 PM](https://hackmd.io/_uploads/BJK83JJEA.png)
:::

**「人臉辨識」已經有直接可用的套件可用，但是需要安裝 cmake 與 dlib，如果想要在辨識人臉後畫出相對應的人臉區域則會需要用到 matplotlib 套件**

:::success
使用 `python -m pip install matplotlib` 指令安裝 **matplotlib** 套件
![Screenshot 2024-05-25 at 12.54.49 PM](https://hackmd.io/_uploads/S1y21x1NC.jpg)
:::

:::danger
安裝 cmake 有兩個部份
1. 一個是在 windows 系統裡安裝 cmake
  - 方法 1: 使用 visual studio 2019 或更新版本安裝 cmake 工具集 
  - 方法 2: 網路尋找 cmake 並進行安裝
3. 在conda 的 env 裡安裝 cmake 套件

使用 Google 尋找 cmake download
![Screenshot 2024-05-25 at 1.02.59 PM](https://hackmd.io/_uploads/HynrWgJEA.png)

開啟網頁後，往下滑動找到符合系統的版本進行下載
<kbd>![Screenshot 2024-05-25 at 1.07.00 PM](https://hackmd.io/_uploads/SyYrzlJER.png)</kbd>

<kbd>![Screenshot 2024-05-20 at 11.18.11 AM](https://hackmd.io/_uploads/SJTcEek4R.png =400x)</kbd>

<kbd>![Screenshot 2024-05-20 at 12.31.46 PM](https://hackmd.io/_uploads/SJ_AVlyVC.png =400x)</kbd>

<kbd>![Screenshot 2024-05-20 at 12.31.56 PM](https://hackmd.io/_uploads/ryT1Be1V0.png =400x)</kbd>

<kbd>![Screenshot 2024-05-20 at 12.32.10 PM](https://hackmd.io/_uploads/SJb_Hl1N0.png =400x)</kbd>

<kbd>![Screenshot 2024-05-20 at 12.32.39 PM](https://hackmd.io/_uploads/SJFC8xJVA.png =400x)</kbd>

<kbd>![Screenshot 2024-05-20 at 12.32.30 PM](https://hackmd.io/_uploads/SJk58lyVA.png =400x)</kbd>

<kbd>![Screenshot 2024-05-20 at 12.32.47 PM](https://hackmd.io/_uploads/SyyGwe1V0.png =400x)</kbd>

<kbd>![Screenshot 2024-05-20 at 12.33.16 PM](https://hackmd.io/_uploads/HkaQDxJ4R.png =400x)</kbd>

**安裝好 cmake 後關掉「終端機 (command prompt)」再重開，然後以 `cmake --version` 指令測試 cmake 版本資訊**

<kbd>![Screenshot 2024-05-25 at 1.30.56 PM](https://hackmd.io/_uploads/SyrUueyEA.png)</kbd>
:::


:::info
**在 conda 環境裡要安裝 cmake，操作如下** 
<kbd>![Screenshot 2024-05-25 at 1.39.48 PM](https://hackmd.io/_uploads/S1vI9gJ40.jpg)</kbd>
:::

:::success
**接下來，在 環境裡安裝 dlib 套件**
<kbd>![Screenshot 2024-05-25 at 1.45.04 PM](https://hackmd.io/_uploads/HkcOoxkEC.png)</kbd>

開啟 https://anaconda.org/ 網頁，如果沒有帳號可以註冊一個 (免費)，有帳號者按 login 登入
<kbd>![Screenshot 2024-05-25 at 1.50.00 PM](https://hackmd.io/_uploads/SJy9nl1EC.jpg)</kbd>

<kbd>![Screenshot 2024-05-25 at 1.54.44 PM](https://hackmd.io/_uploads/SJwPpgJ4A.png)</kbd>

<kbd>![Screenshot 2024-05-25 at 1.56.13 PM](https://hackmd.io/_uploads/H1cpax1NC.jpg)</kbd>

<kbd>![Screenshot 2024-05-25 at 2.05.52 PM](https://hackmd.io/_uploads/BkhLeW1N0.jpg)</kbd>

<kbd>![Screenshot 2024-05-25 at 2.09.53 PM](https://hackmd.io/_uploads/S12HWby4C.jpg)</kbd>
:::

### 使用 face_engine 套件進行臉部偵測

1. 先從網路上找一張有人臉的影像 (我將下載的影像放在 imgs 子目錄下，影像檔名以 family02.jpg 為例)

<kbd>![Screenshot 2024-05-25 at 2.19.44 PM](https://hackmd.io/_uploads/Byb2X-kEA.jpg)</kbd>

2. 建立一個 test.py 的程式檔，程式碼如下

```python=
from face_engine import FaceEngine
import matplotlib.pyplot as plt 

if __name__ == "__main__":
    face_engine = FaceEngine()
    imgName = "imgs/family02.jpg"
    plt.imshow(plt.imread(imgName))
    plt.show()
    boxes, extra = face_engine.find_faces( imgName )
    print( boxes )
    print( extra )
```

<kbd>![Screenshot 2024-05-25 at 2.25.33 PM](https://hackmd.io/_uploads/rkbvHZJ4C.jpg)</kbd>

<kbd>![Screenshot 2024-05-25 at 2.25.11 PM](https://hackmd.io/_uploads/rJndSWkN0.jpg =500x)</kbd>

:::success
**接下來，將找到的人臉範圍資訊以 PIL 套件的 ImageDraw 工具畫上紅色的矩形**

```python=
from face_engine import FaceEngine
import matplotlib.pyplot as plt 
from PIL import Image, ImageDraw

if __name__ == "__main__":
    face_engine = FaceEngine()
    imgName = "imgs/family02.jpg"
    try:
        boxes, extra = face_engine.find_faces( imgName )
        print( boxes )
        img = Image.open(imgName)
        drawImg = ImageDraw.Draw(img)
        for i in range( len( boxes ) ):
            shape =[(boxes[i][0], boxes[i][1]), 
                    (boxes[i][2], boxes[i][3])]
            drawImg.rectangle( shape, outline='red',
                                width=2)
        plt.imshow(img)
        plt.show()
    except:
        print("Error loading image or no faces found in image")
```
<kbd>![Screenshot 2024-05-25 at 2.40.03 PM](https://hackmd.io/_uploads/B1RVYbkER.jpg)</kbd>

:::

## 環境設定 Mac OS
在 Mac 的終端機下建立一個 資料匣，在進入資料匣後以 `code .` 指令開啟 VS Code，如果沒出 VS Code 可能是沒安裝 VS Code 或者 VS Code 在環境變數裡的 Path 設定未設定好

<kbd>![Screenshot 2024-05-25 at 3.09.02 PM](https://hackmd.io/_uploads/Sys3RbyNA.png)
</kbd>

<kbd>![Screenshot 2024-05-25 at 3.12.30 PM](https://hackmd.io/_uploads/Sk2oJf1EA.png =600x)
</kbd>

<kbd>![Screenshot 2024-05-25 at 3.14.17 PM](https://hackmd.io/_uploads/S1PZxz1NR.png)</kbd>

<kbd>![Screenshot 2024-05-25 at 3.15.36 PM](https://hackmd.io/_uploads/Hk7ngzyEC.png)</kbd>


:::info
將剛剛建立的 env 指定為開啟此 workspace 的預設環境 
<kbd>![Screenshot 2024-05-25 at 3.15.51 PM](https://hackmd.io/_uploads/Skj6lGJVR.png)</kbd>
:::

:::success
檢查 conda 與 Python版本
<kbd>![Screenshot 2024-05-25 at 3.20.08 PM](https://hackmd.io/_uploads/SyajGz1VC.png)</kbd>
:::

:::info
在終端機以 `python3 -m pip install face_engine` 指令安裝 face_engine 套件
<kbd>![Screenshot 2024-05-25 at 3.27.48 PM](https://hackmd.io/_uploads/SyntcMyER.png)</kbd>

如果安裝過程出現無法安裝，查看是不是有被防毒軟體阻擋
<kbd>![Screenshot 2024-05-25 at 3.27.55 PM](https://hackmd.io/_uploads/HkwZsfJNC.png =500x)
</kbd>

選擇阻擋事件，然後 點擊 Unblock 放行
<kbd>![Screenshot 2024-05-25 at 3.28.02 PM](https://hackmd.io/_uploads/BkU7jfJ4C.png =500x)
</kbd>

再安裝一次看看
<kbd>![Screenshot 2024-05-25 at 4.04.56 PM](https://hackmd.io/_uploads/SypJ3GyER.png)
</kbd>

寫個測試檔試看看
<kbd>![Screenshot 2024-05-25 at 4.10.28 PM](https://hackmd.io/_uploads/SJdApzJNC.png)
</kbd>
:::

:::warning
在終端機以 `brew install cmake` 在 Mac 作業系統下安裝 cmake
<kbd>![Screenshot 2024-05-25 at 4.07.18 PM](https://hackmd.io/_uploads/BkLohMk4A.png)
</kbd>
:::

:::info
在 terminal 裡使用 conda 安裝 cmake
<kbd>![Screenshot 2024-05-25 at 7.03.01 PM](https://hackmd.io/_uploads/rkUArHkNA.png)
</kbd>

接著再以 `python3 -m pip install cmake` 用 python 的方式安裝 cmake
<kbd>![Screenshot 2024-05-25 at 7.06.08 PM](https://hackmd.io/_uploads/SJl5US1VA.png)
</kbd>
:::

:::success
在終端機下安裝 `conda install dlib`
<kbd>![Screenshot 2024-05-25 at 7.40.29 PM](https://hackmd.io/_uploads/SkwACSk4R.png)
</kbd>

<kbd>![Screenshot 2024-05-25 at 7.38.50 PM](https://hackmd.io/_uploads/Sk4bkI140.png)
</kbd>

<kbd>![Screenshot 2024-05-25 at 7.47.10 PM](https://hackmd.io/_uploads/BJ0XlIyEC.png)
</kbd>

<kbd>![Screenshot 2024-05-25 at 7.45.47 PM](https://hackmd.io/_uploads/B1lIgLkE0.png)
</kbd>

<kbd>![Screenshot 2024-05-25 at 7.50.26 PM](https://hackmd.io/_uploads/rJcae81V0.png)
</kbd>
:::

:::info
準備一張 測試影像 放在 imgs 子目錄裡，撰寫 Python 程式，
<kbd>![Screenshot 2024-05-25 at 11.50.17 PM](https://hackmd.io/_uploads/SkmIttyN0.png)
</kbd>

執行結果
<kbd>![Screenshot 2024-05-25 at 11.54.16 PM](https://hackmd.io/_uploads/B1jg5tkNC.png =250x)
</kbd>

```python=
from face_engine import FaceEngine

if __name__ == '__main__':
    face_engine = FaceEngine()
    imgFileName = 'imgs/Family_02.jpg'
    try:
        boxes, extra = face_engine.find_faces(imgFileName)
        if boxes is not None:
            print('Detected face')
            for box in boxes:
                print(box)
        else:
            print('Failed to detect face')
    except Exception as e:
        print(e)
```
:::

:::warning
測試影像 中的人臉識別，並用 PIL套件及 matplotlib 套件對 找到的人臉 物件畫上紅色矩形
<kbd>
![Screenshot 2024-05-26 at 12.02.22 AM](https://hackmd.io/_uploads/r1T36YJNC.jpg)
</kbd>

```python=
from face_engine import FaceEngine
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt

if __name__ == '__main__':
    face_engine = FaceEngine()
    imgFileName = 'imgs/Family_02.jpg'
    try:
        boxes, extra = face_engine.find_faces(imgFileName)
        print(boxes)
        if boxes is not None:
            img = Image.open(imgFileName)
            drawing = ImageDraw.Draw(img)
            for i in range( len( boxes )):
                shape = [   (boxes[i][0], boxes[i][1]), 
                            (boxes[i][2], boxes[i][3]) ]
                drawing.rectangle( shape, outline ="red", width=3) 
            plt.imshow(img)
            plt.show()
        else:
            print('Failed to detect face')
    except Exception as e:
        print(e)
```

:::

## 人臉特徵學習、佈署與運用
### 人臉特徵學習
:::success
<kbd>![Screenshot 2024-05-26 at 1.00.17 PM](https://hackmd.io/_uploads/rJ5CXBeV0.png)
</kbd>

輸出結果:
<kbd>![Screenshot 2024-05-26 at 1.10.35 PM](https://hackmd.io/_uploads/BylF4HeNC.png =400x)
</kbd>

<kbd>![Screenshot 2024-05-26 at 1.10.14 PM](https://hackmd.io/_uploads/S1j94HeN0.png =500x)
</kbd>

```python=
from face_engine import FaceEngine
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt

if __name__ == '__main__':
    face_engine = FaceEngine()
    imgNames = ['imgs/Andy_Lau_01.jpeg', 'imgs/Andy_Lau_02.jpeg', 
                'imgs/Keanu_Reeves_02.jpeg', 'imgs/Keanu_Reeves_05.jpeg', 
                'imgs/Yi_Fei_03.jpeg', 'imgs/Yi_Fei_04.jpeg']
    try:
        face_engine.fit( imgNames,
                        ['Andy', 'Andy', 'Keanu', 'Keanu', 'YiFei', 'YiFei'] )
        testImg = 'imgs/Andy_Lau_04.jpeg'
        boxes, names = face_engine.make_prediction( testImg )
        if boxes is not None:
            print (names, boxes )
            img = Image.open( testImg )
            drawing = ImageDraw.Draw(img)
            for i in range( len( boxes )):
                shape = [   (boxes[i][0], boxes[i][1]), 
                            (boxes[i][2], boxes[i][3]) ]
                drawing.rectangle( shape, outline ="red", width=3) 
            plt.imshow(img)
            plt.show()
        else:
            print('Failed to detect face')
    except Exception as e:
        print(e)
    
    
```
:::

### 將人臉特徵儲存成特徵檔

:::warning

<kbd>![Screenshot 2024-05-26 at 1.49.27 PM](https://hackmd.io/_uploads/SkHM0rl4R.png)</kbd>

執行結果:
<kbd>![Screenshot 2024-05-26 at 1.54.57 PM](https://hackmd.io/_uploads/HknR0rxNC.png =280x)</kbd>

範例程式碼
```python
from face_engine import FaceEngine

if __name__ == '__main__':
    face_engine = FaceEngine()
    imgNames = ['imgs/Andy_Lau_01.jpeg', 'imgs/Andy_Lau_02.jpeg', 
                'imgs/Keanu_Reeves_02.jpeg', 'imgs/Keanu_Reeves_05.jpeg', 
                'imgs/Yi_Fei_03.jpeg', 'imgs/Yi_Fei_04.jpeg']
    try:
        face_engine.fit( imgNames,
                        ['Andy', 'Andy', 'Keanu', 'Keanu', 'YiFei', 'YiFei'] )
        face_engine.save( 'face_feature.p' )
    except Exception as e:
        print(e)
```
:::

### 讀入人臉特徵檔進行運用
:::info

<kbd>![Screenshot 2024-05-26 at 1.57.01 PM](https://hackmd.io/_uploads/S1Fp1IeER.png)</kbd>

執行結果:
<kbd>![Screenshot 2024-05-26 at 2.01.12 PM](https://hackmd.io/_uploads/HylPlLl4R.png =450x)
</kbd>

<kbd>![Screenshot 2024-05-26 at 2.00.51 PM](https://hackmd.io/_uploads/HkMdlLl4C.png)
</kbd>

範例程式碼:
```python=
from face_engine import load_engine
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt

if __name__ == '__main__':
    face_engine = load_engine( 'face_feature.p' )
    testImg = 'imgs/Yi_Fei_01.jpeg'
    boxes, names = face_engine.make_prediction( testImg )
    if boxes is not None:
        print (names, boxes )
        img = Image.open( testImg )
        drawing = ImageDraw.Draw(img)
        for i in range( len( boxes )):
            shape = [   (boxes[i][0], boxes[i][1]), 
                        (boxes[i][2], boxes[i][3]) ]
            drawing.rectangle( shape, outline ="red", width=3)
        plt.imshow(img)
        plt.show()
    else:
        print('Failed to detect face')
```
:::

## 使用 face-recognition 模組分析人臉特徵

**`face_recognition`** 模組的主要用途：

1. **人臉識別**： `face_recognition` 可以從圖片或視訊中檢測並識別人臉。它能夠定位測試影像或視訊中的人臉與已知的人臉進行比對
2. **人臉位置檢測**：此模組可以檢測圖像或視頻中人臉的位置。它能夠回傳每張人臉在圖像中的座標，進而可以提供後續的處理和分析
3. **人臉特徵提取**：`face_recognition` 可以提取人臉的特徵碼，這些特徵碼是128維的向量，能夠用於比較和辨識不同的人臉
4. **人臉比對**：利用提取到的特徵碼，可以進行人臉之間的比對和配對。這使得可以驗證圖像中的人臉是否屬於已知的人
5. **人臉分群**：模組還可以將多張人臉影像分群，依特徵碼將相似的人臉分為一組
 
`face_recognition` 模組的主要目的是提供簡單且強大的工具，用於**人臉識別**和**分析**，適用於**安全驗證**、**監控系統**、**照片管理**等多種應用場景。

face_recognition 模組是基於深度學習的人臉識別庫，提供了多種功能來檢測和識別影像中的人臉。以下是主要函數：
1. **load_image_file(file, mode='RGB')**
  - 功能：從文件中載入影像並轉換為 numpy 陣列。
  - 參數：
    - **file**：影像檔案的路徑與檔名
    - **mod**e：影像模式（預設為'RGB'）
2. **face_locations(img, number_of_times_to_upsample=1, model='hog')**
  - 功能：檢測影像中人臉的位置
  - 參數：
    - **img**：影像的 numpy 陣列
    - **number_of_times_to_upsample**：影像上採樣的次數以檢測更多小型人臉
    - **model**：檢測模型（'hog' 或 'cnn'）
3. **face_encodings(face_image, known_face_locations=None, num_jitters=1, model='small')**
  - 功能：計算影像中每張人臉的128維特徵向量
  - 參數：
    - **face_image**：包含人臉的影像 numpy 陣列
    - **known_face_locations**：已知的人臉位置（可選）
    - **num_jitters**：抖動次數，增加特徵碼的準確性
    - **model**：特徵碼模型（'small' 或 ‘large'）
  - 補充說明:
    - **num_jitter**s 參數指定了在計算人臉特徵碼時，對每張人臉進行多少次隨機變換（抖動）。每次抖動會稍微改變影像中人臉的角度、位置或比例，然後重新計算特徵碼。最終的特徵碼是所有這些抖動結果的平均值。
    - **預設值**：預設值為1，表示不進行額外的抖動。這適用於影像品質較高且人臉特徵明顯的情況。

### <span style="background-color: #99ddff">安裝 face_recognition 套件</span>
:::warning
#### **Mac OS**
在終端機使用  **`conda install face_recognition`** 指令安裝 **face_recognition** 套件
<kbd>![Screenshot 2024-05-26 at 4.43.20 PM](https://hackmd.io/_uploads/HkSP_Ke4C.png)</kbd>

在終端機使用  **`python3 -m pip install face_recognition`** 指令安裝 **face_recognition** 套件
<kbd>![Screenshot 2024-05-26 at 4.44.02 PM](https://hackmd.io/_uploads/BymUFtxE0.png)
</kbd>
:::

### <span style="background-color: #99ddff">使用 face_recognition 人臉識別</span>

#### 範例一
:::success
<kbd>![Screenshot 2024-05-26 at 5.41.19 PM](https://hackmd.io/_uploads/rkKYvteNA.png)
</kbd>

執行結果:
<kbd>![Screenshot 2024-05-26 at 5.58.14 PM](https://hackmd.io/_uploads/Sk9dqYg4R.png)
</kbd>
<kbd>![Screenshot 2024-05-26 at 6.36.43 PM](https://hackmd.io/_uploads/SJG1b5gNA.png =350x)
</kbd>

```python=
import face_recognition
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt

if __name__ == "__main__":
    imgX = 'imgs/Yi_Fei_05.jpeg'
    img_load = face_recognition.load_image_file( imgX )
    boxes = face_recognition.face_locations( img_load )
    if boxes is not None:
        print( boxes )
        img = Image.open( imgX )
        drawing = ImageDraw.Draw(img)
        for i in range( len( boxes )):
            shape = [   (boxes[i][3], boxes[i][0]), 
                        (boxes[i][1], boxes[i][2]) ]
            drawing.rectangle( shape, outline ="red", width=3)
        plt.imshow(img)
        plt.show()
    else:
        print('Failed to detect face')
```
:::

#### 範例二
:::info
使用多人照片測試看看
<kbd>![Screenshot 2024-05-26 at 6.52.11 PM](https://hackmd.io/_uploads/rkn9EqeNR.png)</kbd>

<kbd>![Screenshot 2024-05-26 at 6.39.55 PM](https://hackmd.io/_uploads/SklMBqxEA.jpg)</kbd>

<kbd>![Screenshot 2024-05-26 at 6.40.09 PM](https://hackmd.io/_uploads/BJthV5gVC.png =350x)</kbd>


```python=
import face_recognition
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt

if __name__ == "__main__":
    imgX = 'imgs/Family_02.jpg'
    img_load = face_recognition.load_image_file( imgX )
    boxes = face_recognition.face_locations( img_load )
    if boxes is not None:
        
        img = Image.open( imgX )
        drawing = ImageDraw.Draw(img)
        for i in range( len( boxes )):
            print( f'{i} => {boxes[i]}' )
            shape = [   (boxes[i][3], boxes[i][0]), 
                        (boxes[i][1], boxes[i][2]) ]
            drawing.rectangle( shape, outline ="red", width=3)
        plt.imshow(img)
        plt.show()
    else:
        print('Failed to detect face')
```
:::

## 臉部特徵資訊萃取

:::success


<kbd>![Screenshot 2024-05-26 at 6.52.11 PM](https://hackmd.io/_uploads/rkzxO5x40.png)</kbd>

#### 執行結果
<kbd>![Screenshot 2024-05-26 at 7.08.13 PM](https://hackmd.io/_uploads/rkm_uce4R.png)</kbd>

face landmark 的項目如下:
- **chin (臉頰)**
- **left_eyebrow (左眉毛)**
- **right_eyebrow (右眉毛)**
- **nose_bridge (鼻樑)**
- **nose_tip (鼻尖)**
- **left_eye (左眼睛)**
- **right_eye (右眼睛)**
- **top_lip (上唇)**
- **bottom_lip (下唇)**

<kbd>![Screenshot 2024-05-26 at 7.35.11 PM](https://hackmd.io/_uploads/SJypkjl4A.png =400x)</kbd>

```python=
import face_recognition

if __name__ == "__main__":
    imgX = 'imgs/Andy_Lau_04.jpeg'
    img_load = face_recognition.load_image_file( imgX )
    landmarks = face_recognition.face_landmarks( img_load )
    if landmarks is not None:
        for i in range( len( landmarks )):
            print( f'{i}-th object ')
            for key, value in landmarks[i].items():
                print( f'{key} => {value}' )
    else:
        print('Failed to detect face')
```
:::

:::warning
#### **尋找完臉部 特徵 後畫出特徵位置**

<kbd>![Screenshot 2024-05-26 at 7.45.08 PM](https://hackmd.io/_uploads/BJ39bsgVC.png)
</kbd>

**執行結果**
<kbd>![Screenshot 2024-05-26 at 7.44.44 PM](https://hackmd.io/_uploads/B1VdWox4R.png)
</kbd>

<kbd>![Screenshot 2024-05-26 at 7.45.43 PM](https://hackmd.io/_uploads/BJb2-olEC.png)
</kbd>

**範例程式碼**
```python=
import face_recognition
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt

if __name__ == "__main__":
    imgX = 'imgs/Andy_Lau_04.jpeg'
    img_load = face_recognition.load_image_file( imgX )
    landmarks = face_recognition.face_landmarks( img_load )
    if landmarks is not None:
        img = Image.open( imgX )
        drawing = ImageDraw.Draw(img)
        for i in range( len( landmarks )):
            print( f'{i}-th object ')
            for key, value in landmarks[i].items():
                drawing.line( value, fill ="blue", width=5)
                print( f'{key} => {value}' )
        plt.imshow(img)
        plt.show()
    else:
        print('Failed to detect face')
```
:::

:::info
#### **比對臉部特徵判斷是何人**

<kbd>![Screenshot 2024-05-26 at 8.59.36 PM](https://hackmd.io/_uploads/Hye1EheVR.png)</kbd>

**執行結果**
<kbd>![Screenshot 2024-05-26 at 8.53.18 PM](https://hackmd.io/_uploads/H1L7V2lNC.png)</kbd>

<kbd>![Screenshot 2024-05-26 at 8.53.43 PM](https://hackmd.io/_uploads/rkO-V3eEC.png)</kbd>

```python=
import face_recognition
from PIL import Image
import matplotlib.pyplot as plt

if __name__ == "__main__":
    imgNames = ['imgs/Andy_Lau_01.jpeg', 'imgs/Andy_Lau_02.jpeg',
                'imgs/Andy_Lau_03.jpeg',
                'imgs/Keanu_Reeves_01.jpeg', 'imgs/Keanu_Reeves_02.jpeg', 
                'imgs/Keanu_Reeves_03.jpeg',
                'imgs/Yi_Fei_01.jpeg', 'imgs/Yi_Fei_02.jpeg',
                'imgs/Yi_Fei_02.jpeg']
    load_imgs = []
    for img in imgNames:
        img_load = face_recognition.load_image_file( img )
        load_imgs.append( img_load )
    face_codes = []
    for img in load_imgs:
        face_codes.append( face_recognition.face_encodings( img )[0] )
    names = ['Andy', 'Andy', 'Andy', 'Keanu', 'Keanu', 'Keanu', 'YiFei', 'YiFei', 'YiFei']
    testImg = 'imgs/Keanu_Reeves_04.jpeg'
    testImg_load = face_recognition.load_image_file( testImg )
    test_face_code = face_recognition.face_encodings( testImg_load )[0]
    results = face_recognition.compare_faces( face_codes, test_face_code )
    print( results )
    img = Image.open( testImg )
    plt.imshow(img)
    plt.show()
    if True in results:
        print( f'The person <<{names[ results.index( True )]}>> is in the test image' )
    else:
        print('The test image does not contain any of the persons in the database')
```
:::

:::warning
#### **使用 face_recognition 中的 face_distance( ) 計算測試影像裡的人物臉部特徵與 "已知" 人物的臉部特徵距離**

<kbd>![Screenshot 2024-05-26 at 9.27.38 PM](https://hackmd.io/_uploads/ryf_HalV0.png)</kbd>

**執行結果**
<kbd>![Screenshot 2024-05-26 at 9.27.53 PM](https://hackmd.io/_uploads/HkCqS6gE0.png)</kbd>

<kbd>![Screenshot 2024-05-26 at 9.28.15 PM](https://hackmd.io/_uploads/ry93STlVC.png)</kbd>

**範例程式碼**
```python=
import face_recognition
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

if __name__ == "__main__":
    imgNames = ['imgs/Andy_Lau_01.jpeg', 'imgs/Andy_Lau_02.jpeg',
                'imgs/Andy_Lau_03.jpeg',
                'imgs/Keanu_Reeves_01.jpeg', 'imgs/Keanu_Reeves_02.jpeg', 
                'imgs/Keanu_Reeves_03.jpeg',
                'imgs/Yi_Fei_01.jpeg', 'imgs/Yi_Fei_02.jpeg',
                'imgs/Yi_Fei_03.jpeg']
    load_imgs = []
    for img in imgNames:
        img_load = face_recognition.load_image_file( img )
        load_imgs.append( img_load )
    face_codes = []
    for img in load_imgs:
        face_codes.append( face_recognition.face_encodings( img )[0] )
    names = ['Andy', 'Andy', 'Andy', 'Keanu', 'Keanu', 'Keanu', 'YiFei', 'YiFei', 'YiFei']
    testImg = 'imgs/Yi_Fei_05.jpeg'
    testImg_load = face_recognition.load_image_file( testImg )
    test_face_code = face_recognition.face_encodings( testImg_load )[0]
    distance = face_recognition.face_distance( face_codes, test_face_code )
    print( distance )

    if min( distance ) < 0.6:
        print( f'The person <<{names[ np.argmin(distance) ]}>> is in the test image with feature distance {min(distance)}' )
    else:
        print('The test image does not contain any of the persons in the database')
    img = Image.open( testImg )
    plt.imshow(img)
    plt.show()
```
:::