機器學習與AI技術的快速發展已在電腦視覺領域於物體檢測與識別方面取得顯著進展。然而,要打造一個能識別人們幽默與娛樂感的系統,對程式設計師而言仍是個挑戰,因為喜劇與娛樂具有主觀性,取決於個人品味與文化背景。因此,精確判斷個人覺得何者有趣或愉悅的系統設計頗具難度。
儘管如此,電腦視覺在面部識別與辨識方面已取得重大進展,並廣泛應用於安全、監控及生物識別等領域。面部識別技術主要透過分析與比對個人面部特徵與已知面孔資料庫來辨識個體。面部辨識則涉及將某人的面孔與其身份匹配,運用演算法提取如眼睛間距、鼻形曲線及下巴角度等面部特徵,生成獨特的面部簽名。
面部識別與辨識技術
有各種方法用於面部識別與辨識,但本教程將聚焦於三種技術,概述其優缺點。
1. 模板基礎方法
首先,基於模板的方法將目標臉部的特徵與模板或參考圖像中的特徵進行比較。模板圖像包含多個面部特徵,如眼睛、鼻子、嘴巴的位置以及它們之間的距離。該技術隨後將目標臉部與模板圖像進行比對,以確定是否存在匹配。Eigenfaces 是最常見的基於模板的技術之一,它使用主成分分析(PCA)來降低面部圖像的維度並提取最相關的特徵。
優點
- 與高品質模板配合時非常準確
- 能處理光照和面部表情的變化
缺點
- 需要高品質模板以獲得準確結果
- 可能計算成本較高
2. 基於特徵的方法
其次,基於特徵的技術從面部提取特徵,如眼睛的形狀、眉毛之間的距離以及嘴唇的曲率。然後,該方法將這些特徵與已知面部的數據庫中的特徵進行比較,以識別目標臉部。典型的基於特徵的技術包括局部二值模式(LBP)和尺度不變特徵變換(SIFT)。
優點
- 相對快速且高效
- 適用於低解析度圖像
缺點
- 在不同光照條件下可能效果不佳
- 可能對面部表情或姿勢的變化不夠健壯
3. 基於深度學習的方法
最後,基於深度學習的方法使用深度神經網絡直接從面部圖像中學習特徵。網絡在大量面部圖像數據集上進行訓練,以識別與面部識別相關的模式和特徵。典型的基於深度學習的方法包括卷積神經網絡(CNN)和孿生網絡。
優點
- 在大數據集上實現高準確率
- 能處理面部表情和姿態的變化
缺點
- 需要大量的訓練數據
- 計算成本高昂
注意:面部識別和識別有多種技術。
使用Python和OpenCV進行面部識別和識別
隨著OpenCV等強大庫的可用性以及機器學習算法的進步,使用Python開發面部識別和識別系統變得前所未有的容易。OpenCV提供了豐富的圖像處理功能和工具,特別適用於面部識別任務,如面部檢測、特徵提取和匹配。它還提供了現成的模型,如Haar級聯分類器用於面部檢測,以及VGG或ResNet用於標記檢測到的面部。
OpenCV 提供多種人臉標記模型,如 Eigenfaces、Fisherfaces 和局部二元模式直方圖 (LBPH)。我們訓練這些模型以通過展示我們希望識別的個體的圖像來識別特定個體。Eigenfaces 使用主成分分析 (PCA) 從較小的部分構建面部圖像,而 Fisherfaces 利用線性判別分析 (LDA) 區分面部。LBPH 比較面部的質地與已知面部。
面部識別
導入依賴項
導入必要的庫。
import numpy as np
import cv2
import matplotlib.pyplot as plt
from IPython.display import Image
from google.colab import drive
drive.mount('/content/drive')
加載預訓練模型和圖像
OpenCV 提供了一套預訓練的 `Haar Cascade 分類器` 用於檢測各種對象,包括面部。`cv2.CascadeClassifier` 是一個表示 Haar Cascade 分類器的類。cv2.data.haarcascades 是包含預訓練模型的目錄的路徑。`haarcascade_frontalface_default.xml` 是包含預訓練面部檢測模型的文件。該模型可在 GitHub 上免費下載。
# 加載預訓練的面部檢測模型
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
使用 OpenCV 的 `imread()` 函數加載輸入圖像 `image1.jpg`(可以是您選擇的圖像)。然後使用 OpenCV 的 `cvtColor()` 函數將圖像轉換為灰度。灰度圖像是面部檢測算法所必需的。
# 載入圖像並轉換為灰階
img = cv2.imread('/content/drive/MyDrive/Face Detection/image1.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 顯示圖像
plt.imshow(gray)
以下這行使用CascadeClassifier類別的detectMultiScale()方法在灰階圖像中檢測臉部。detectMultiScale()方法接受以下參數:
`gray`:灰階圖像
`scaleFactor`:指定每次圖像縮小比例的參數。1.3的值意味著每次縮小30%。
`minNeighbors`:指定每個候選矩形應保留的鄰居數量,較高的值會導致更少的檢測但信心更高。
detectMultiScale()方法返回一個矩形列表,其中檢測到臉部。每個矩形代表一個四元組`(x,y,w,h)`,表示矩形的左上角座標`(x,y)`及其寬度`w`和高`h`。
# 在灰階圖像中檢測臉部
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
在臉部區域繪製矩形
讓我們建立一個迴圈,在原始圖像中繪製矩形圍繞檢測到的臉部。cv2.rectangle()函數接受以下參數:
`img`:原始圖像。
`(x,y)`:矩形的左上角座標。
`(x+w,y+h)`:矩形的右下角座標。
`(255,0,0)`:以RGB格式表示繪製的矩形顏色,(255,0,0)代表藍色。
`5`:矩形邊界的厚度,單位為像素。
# 在偵測到的人臉周圍繪製矩形
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),5)
# 顯示繪製矩形後的圖像
# 展示帶有偵測到人臉的圖像
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
# 按名稱保存偵測到的圖像
cv2.imwrite('detected_image.jpg', img)
# 確認保存的圖像是否存在
detected_image=cv2.imread("detected_image.jpg", 1)
gray_channels_reversed = detected_image[:, :, ::-1]
plt.imshow(gray_channels_reversed)
人臉識別
我們將不進行上述解釋,而是使用上述保存的偵測圖像來確認模型是否能夠通過提供不同的圖像進行識別。
導入依賴項
import numpy as np
import cv2
import matplotlib.pyplot as plt
import dlib
from imutils import face_utils
from scipy.spatial.distance import cosine
from sklearn.metrics.pairwise import cosine_similarity
加載人臉檢測模型和人臉特徵點檢測器
`dlib.get_frontal_face_detector()`函數返回一個預訓練的人臉檢測模型,能夠在圖像中檢測人臉。更多信息,請查閱dlib.net函數。同時,下載特徵點檢測器。
# 加載人臉檢測模型和人臉特徵點檢測器
face_detector = dlib.get_frontal_face_detector()
landmark_detector = dlib.shape_predictor('/content/drive/MyDrive/Face Detection/shape_predictor_68_face_landmarks_GTX.dat')
# 加載已偵測的圖像
img1 = cv2.imread('/content/drive/MyDrive/Face Detection/detected_image.jpg')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
# 偵測圖像中的人臉及人臉特徵點
rects1 = face_detector(gray1, 1)
landmarks1 = landmark_detector(gray1, rects1[0])
landmarks1 = face_utils.shape_to_np(landmarks1)
# 加載另一張圖像以與先前加載的圖像進行比較
img2 = cv2.imread('/content/drive/MyDrive/Face Detection/001_d3323f3c.jpg')
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
### 設定模型參數
# 偵測第二張圖像的臉部及臉部特徵點
rects2 = face_detector(gray2, 1)
landmarks2 = landmark_detector(gray2, rects2[0])
landmarks2 = face_utils.shape_to_np(landmarks2)
# 透過計算臉部特徵點之間的歐氏距離來提取兩張圖像的特徵
features1 = np.zeros(68)
features2 = np.zeros(68)
for i in range(68):
features1[i] = np.linalg.norm(landmarks1[i] - landmarks1[0])
features2[i] = np.linalg.norm(landmarks2[i] - landmarks2[0])
#### 基於相似性進行訓練
# 計算兩個特徵向量之間的餘弦相似度
score = cosine(features1, features2)
# 檢查分數是否低於某個閾值(例如0.5)以判定兩張臉是否匹配
if score < 0.5:
print("The model did not recognize Joseph in one or both of the images..")
else:
print("The model recognized Joseph in both images.")
結論
在本教學中,您已學習如何使用Python OpenCV進行臉部識別與辨識,了解其運作原理、應用場景及實施方法。本專案的程式碼可從GitHub Repo取得。
Source:
https://dzone.com/articles/facial-recognition-and-identification-in-computer