我們已經擁有一份人臉圖片資料集、訓練好的Deepface模型,我們要怎麼將圖像特徵取出並做嵌入呢?
DeepFace提供了專門的represent()
函數來提取人臉的特徵向量 。這個函數會將人臉圖像轉換為多維向量表示:
from deepface import DeepFace
import numpy as np
# 提取單張圖片的特徵向量
embedding_objs = DeepFace.represent(
img_path="your_image_path.jpg",
model_name="VGG-Face", # 或其他模型
detector_backend="opencv"
)
# 獲取嵌入向量
embedding = embedding_objs[^0]["embedding"]
對於您的資料集,可以批量提取所有圖片的特徵向量:
import os
import pandas as pd
def extract_features_batch(image_folder, labels):
features = []
image_labels = []
for filename in os.listdir(image_folder):
if filename.endswith(('.jpg', '.png', '.jpeg')):
try:
img_path = os.path.join(image_folder, filename)
# 提取特徵向量
embedding_objs = DeepFace.represent(
img_path=img_path,
model_name="VGG-Face",
enforce_detection=False
)
embedding = embedding_objs[^0]["embedding"]
features.append(embedding)
# 根據檔名或資料夾結構確定標籤
label = determine_label(filename) # 實作您的標籤邏輯
image_labels.append(label)
except Exception as e:
print(f"處理 {filename} 時發生錯誤: {e}")
return np.array(features), np.array(image_labels)
DeepFace 會載入其內部包裝的 Facenet 模型(可能是某個預訓練版本)並對處理後的臉部影像做 forward pass,得到 embedding 向量。
# 使用Facenet提取特徵
embedding_objs = DeepFace.represent(
img_path="image_path.jpg",
model_name="Facenet"
)
提取的特徵向量可以用於訓練情感分類器:
# 拿取圖片的標籤(label),也就是說圖片必須以label_....的方式命名才能讀取,這不太好之後要改善
def determine_label(filename):
# Example: If filenames are like 'angry_001.jpg', 'happy_002.jpg', etc.
# You might split the filename and take the first part as the label
label = filename.split('_')[0]
return label
# 給出圖片路徑
image_folder_path = "/content/your_images" # 假設你的圖片在 'your_images' 資料夾
# 萃取你的照片的特徵和標籤
features, labels = extract_features_batch(image_folder_path, None)
print(f"Extracted features shape: {features.shape}")
print(f"Extracted labels shape: {labels.shape}")
特徵向量還可以用於計算人臉之間的相似度 :
from scipy.spatial.distance import cosine
def calculate_similarity(embedding1, embedding2):
# 使用餘弦相似度
similarity = 1 - cosine(embedding1, embedding2)
return similarity
為了提高準確性,可以使用多張不同角度和光線條件的圖片提取特徵,然後將向量平均化 :
def extract_averaged_features(image_paths):
embeddings = []
for img_path in image_paths:
embedding_objs = DeepFace.represent(
img_path=img_path,
model_name="deepface"
)
embeddings.append(embedding_objs[^0]["embedding"])
# 平均化特徵向量
averaged_embedding = np.mean(embeddings, axis=0)
return averaged_embedding
建議使用適當的資料庫來儲存提取的特徵向量。對於中小型專案,可以使用SQLite :
import sqlite3
import pickle
def save_embeddings_to_db(embeddings, labels, db_path):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS face_embeddings (
id INTEGER PRIMARY KEY,
embedding BLOB,
label TEXT
)
''')
for embedding, label in zip(embeddings, labels):
embedding_blob = pickle.dumps(embedding)
cursor.execute(
"INSERT INTO face_embeddings (embedding, label) VALUES (?, ?)",
(embedding_blob, label)
)
conn.commit()
conn.close()
通過這些方法,您可以有效地從DeepFace模型中提取人臉特徵並生成嵌入向量,用於後續的情感識別或其他分析任務 。
實作目標: FaceNet做圖像嵌入
實作: 發現Deepface的維度高達4096,遇到了一些時間和算力的限制,選擇了FaceNet做圖像嵌入
實作放在colab