|
import cv2
import os
import numpy as np
from PIL import Image
# 創建人臉檢測器和辨識器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 準備訓練數據
def get_images_and_labels(data_folder):
face_samples = []
ids = []
id_names = {} # 用於映射ID到名字的字典
# 遍歷數據文件夾中的每個子文件夾(每個人一個文件夾)
for root, dirs, files in os.walk(data_folder):
for subdir in dirs:
subject_path = os.path.join(root, subdir)
# 獲取當前人物的ID(使用文件夾名稱作為ID)
current_id = int(subdir)
id_names[current_id] = subdir # 存儲ID到名字的映射
# 遍歷當前人物的所有圖片
for filename in os.listdir(subject_path):
if filename.startswith("."):
continue # 跳過隱藏文件
path = os.path.join(subject_path, filename)
# 將圖片轉換為灰度圖
pil_image = Image.open(path).convert('L')
image_np = np.array(pil_image, 'uint8')
# 檢測人臉
faces = face_cascade.detectMultiScale(image_np)
for (x, y, w, h) in faces:
face_samples.append(image_np[y:y+h, x:x+w])
ids.append(current_id)
return face_samples, ids, id_names
# 訓練人臉辨識器
def train_recognizer(data_folder):
print("正在訓練人臉辨識器...")
faces, ids, id_names = get_images_and_labels(data_folder)
recognizer.train(faces, np.array(ids))
recognizer.save('trainer.yml')
print("訓練完成!已保存訓練數據到 trainer.yml")
return id_names
# 人臉辨識函數
def recognize_faces():
# 加載訓練數據
if not os.path.exists('trainer.yml'):
print("錯誤:找不到訓練數據文件 (trainer.yml),請先運行訓練程序。")
return
recognizer.read('trainer.yml')
# 初始化攝像頭
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 檢測人臉
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
for (x, y, w, h) in faces:
# 繪製人臉矩形框
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 進行辨識
id_, confidence = recognizer.predict(gray[y:y+h, x:x+w])
# 計算置信度百分比
confidence_percent = round(100 - confidence)
# 如果置信度高於50%,則顯示辨識結果
if confidence_percent > 50:
name = id_names.get(id_, f"未知 ({id_})")
text = f"{name} ({confidence_percent}%)"
else:
text = "未知"
cv2.putText(frame, text, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
# 顯示結果
cv2.imshow('人臉辨識', frame)
# 按'q'退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
# 主程序
if __name__ == "__main__":
# 數據文件夾路徑(每個人一個子文件夾,文件夾名稱為ID)
data_folder = "dataset"
# 如果數據文件夾不存在,創建它
if not os.path.exists(data_folder):
os.makedirs(data_folder)
print(f"已創建數據文件夾: {data_folder}")
print("請在該文件夾中為每個人創建子文件夾,文件夾名稱為數字ID,並放入該人的照片。")
else:
# 訓練或辨識
choice = input("輸入 'train' 訓練模型,或 'recognize' 進行辨識: ").lower()
if choice == 'train':
id_names = train_recognizer(data_folder)
elif choice == 'recognize':
# 加載ID到名字的映射
id_names = {}
for root, dirs, files in os.walk(data_folder):
for subdir in dirs:
id_names[int(subdir)] = subdir
recognize_faces()
else:
print("無效的選擇。")
# OpenCV 人臉辨識程式
以下是一個使用OpenCV進行人臉辨識的Python程式,可以辨識不同的人臉。這個程式使用了OpenCV的預訓練人臉檢測模型,並結合LBPH (Local Binary Patterns Histograms) 人臉辨識器來訓練和辨識不同的人。
## 完整程式碼
```python
import cv2
import os
import numpy as np
from PIL import Image
# 創建人臉檢測器和辨識器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 準備訓練數據
def get_images_and_labels(data_folder):
face_samples = []
ids = []
id_names = {} # 用於映射ID到名字的字典
# 遍歷數據文件夾中的每個子文件夾(每個人一個文件夾)
for root, dirs, files in os.walk(data_folder):
for subdir in dirs:
subject_path = os.path.join(root, subdir)
# 獲取當前人物的ID(使用文件夾名稱作為ID)
current_id = int(subdir)
id_names[current_id] = subdir # 存儲ID到名字的映射
# 遍歷當前人物的所有圖片
for filename in os.listdir(subject_path):
if filename.startswith("."):
continue # 跳過隱藏文件
path = os.path.join(subject_path, filename)
# 將圖片轉換為灰度圖
pil_image = Image.open(path).convert('L')
image_np = np.array(pil_image, 'uint8')
# 檢測人臉
faces = face_cascade.detectMultiScale(image_np)
for (x, y, w, h) in faces:
face_samples.append(image_np[y:y+h, x:x+w])
ids.append(current_id)
return face_samples, ids, id_names
# 訓練人臉辨識器
def train_recognizer(data_folder):
print("正在訓練人臉辨識器...")
faces, ids, id_names = get_images_and_labels(data_folder)
recognizer.train(faces, np.array(ids))
recognizer.save('trainer.yml')
print("訓練完成!已保存訓練數據到 trainer.yml")
return id_names
# 人臉辨識函數
def recognize_faces():
# 加載訓練數據
if not os.path.exists('trainer.yml'):
print("錯誤:找不到訓練數據文件 (trainer.yml),請先運行訓練程序。")
return
recognizer.read('trainer.yml')
# 初始化攝像頭
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 檢測人臉
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
for (x, y, w, h) in faces:
# 繪製人臉矩形框
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 進行辨識
id_, confidence = recognizer.predict(gray[y:y+h, x:x+w])
# 計算置信度百分比
confidence_percent = round(100 - confidence)
# 如果置信度高於50%,則顯示辨識結果
if confidence_percent > 50:
name = id_names.get(id_, f"未知 ({id_})")
text = f"{name} ({confidence_percent}%)"
else:
text = "未知"
cv2.putText(frame, text, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
# 顯示結果
cv2.imshow('人臉辨識', frame)
# 按'q'退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
# 主程序
if __name__ == "__main__":
# 數據文件夾路徑(每個人一個子文件夾,文件夾名稱為ID)
data_folder = "dataset"
# 如果數據文件夾不存在,創建它
if not os.path.exists(data_folder):
os.makedirs(data_folder)
print(f"已創建數據文件夾: {data_folder}")
print("請在該文件夾中為每個人創建子文件夾,文件夾名稱為數字ID,並放入該人的照片。")
else:
# 訓練或辨識
choice = input("輸入 'train' 訓練模型,或 'recognize' 進行辨識: ").lower()
if choice == 'train':
id_names = train_recognizer(data_folder)
elif choice == 'recognize':
# 加載ID到名字的映射
id_names = {}
for root, dirs, files in os.walk(data_folder):
for subdir in dirs:
id_names[int(subdir)] = subdir
recognize_faces()
else:
print("無效的選擇。")
```
## 使用說明
1. **準備數據集**:
- 創建一個名為 `dataset` 的文件夾
- 在 `dataset` 中為每個人創建一個子文件夾,文件夾名稱使用數字ID(例如:1, 2, 3...)
- 在每個人的文件夾中放入該人的多張照片(最好有10-20張,包含不同角度和表情)
2. **訓練模型**:
- 運行程序並選擇 `train` 選項
- 程式會讀取 `dataset` 文件夾中的圖片並訓練模型
- 訓練完成後會生成 `trainer.yml` 文件
3. **進行辨識**:
- 運行程序並選擇 `recognize` 選項
- 程式會打開攝像頭並開始實時辨識人臉
- 按 `q` 鍵退出
## 進階改進
1. **提高準確率**:
- 增加更多訓練圖片
- 使用更高質量的圖片
- 嘗試不同的辨識算法(如EigenFace或FisherFace)
2. **添加新功能**:
- 添加註冊新用戶的功能
- 保存辨識記錄
- 增加人臉特徵點檢測
3. **性能優化**:
- 使用多線程處理
- 調整檢測參數(scaleFactor, minNeighbors等)
- 使用GPU加速
這個程式提供了基本的人臉辨識功能,你可以根據需要進一步擴展和改進它。
|
本帖子中包含更多資源
您需要 登錄 才可以下載或查看,沒有帳號?立即註冊
x
|