使用Python的OpenCV库实现人脸检测功能
import cv2
import numpy as np
from PIL import Image, ImageTk
import tkinter as tk
from tkinter import ttk, messagebox
class FaceRecognitionApp:
def __init__(self, root):
self.root = root
self.root.title("人脸识别演示系统")
self.root.geometry("900x650")
self.root.configure(bg="#2c3e50")
# 加载Haar级联分类器
self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 创建界面
self.create_widgets()
# 摄像头状态
self.camera_active = False
self.cap = None
# 人脸统计
self.face_count = 0
self.max_faces_detected = 0
def create_widgets(self):
# 标题
title_frame = tk.Frame(self.root, bg="#3498db", height=80)
title_frame.pack(fill="x", padx=10, pady=10)
title_label = tk.Label(title_frame, text="人脸识别演示系统", font=("Arial", 24, "bold"),
fg="white", bg="#3498db", pady=15)
title_label.pack()
# 主内容区域
main_frame = tk.Frame(self.root, bg="#2c3e50")
main_frame.pack(fill="both", expand=True, padx=20, pady=10)
# 左侧 - 摄像头画面
left_frame = tk.Frame(main_frame, bg="#34495e")
left_frame.pack(side="left", fill="both", expand=True, padx=(0, 10))
self.camera_label = tk.Label(left_frame, bg="black", width=60, height=25)
self.camera_label.pack(padx=10, pady=10)
# 右侧 - 控制面板
right_frame = tk.Frame(main_frame, bg="#34495e", width=300)
right_frame.pack(side="right", fill="y", padx=(10, 0))
# 控制面板标题
control_title = tk.Label(right_frame, text="控制面板", font=("Arial", 16, "bold"),
fg="white", bg="#3498db", width=20, pady=8)
control_title.pack(fill="x", pady=(0, 15))
# 按钮区域
btn_frame = tk.Frame(right_frame, bg="#34495e")
btn_frame.pack(fill="x", padx=15, pady=10)
self.start_btn = tk.Button(btn_frame, text="启动摄像头", font=("Arial", 12),
bg="#2ecc71", fg="white", width=15, command=self.toggle_camera)
self.start_btn.pack(pady=5)
tk.Button(btn_frame, text="保存当前画面", font=("Arial", 12),
bg="#9b59b6", fg="white", width=15, command=self.save_image).pack(pady=5)
tk.Button(btn_frame, text="退出系统", font=("Arial", 12),
bg="#e74c3c", fg="white", width=15, command=self.exit_app).pack(pady=5)
# 统计信息
stats_frame = tk.Frame(right_frame, bg="#34495e", relief="groove", bd=2)
stats_frame.pack(fill="x", padx=15, pady=20)
stats_title = tk.Label(stats_frame, text="检测统计", font=("Arial", 14, "bold"),
fg="#3498db", bg="#34495e")
stats_title.pack(pady=(10, 15))
self.face_count_label = tk.Label(stats_frame, text="检测到人脸: 0", font=("Arial", 12),
fg="white", bg="#34495e")
self.face_count_label.pack(pady=5)
self.max_face_label = tk.Label(stats_frame, text="最大同时检测数: 0", font=("Arial", 12),
fg="white", bg="#34495e")
self.max_face_label.pack(pady=5)
# 信息区域
info_frame = tk.Frame(right_frame, bg="#34495e", relief="groove", bd=2)
info_frame.pack(fill="x", padx=15, pady=(0, 20))
info_title = tk.Label(info_frame, text="系统信息", font=("Arial", 14, "bold"),
fg="#3498db", bg="#34495e")
info_title.pack(pady=(10, 5))
info_text = tk.Label(info_frame, text="使用OpenCV Haar级联分类器进行人脸检测。\n\n"
"该系统可以实时检测摄像头画面中的人脸。",
font=("Arial", 10), fg="white", bg="#34495e", justify="left")
info_text.pack(pady=5, padx=10)
# 状态栏
self.status_bar = tk.Label(self.root, text="就绪", bd=1, relief="sunken", anchor="w",
font=("Arial", 10), bg="#34495e", fg="white")
self.status_bar.pack(side="bottom", fill="x", padx=10, pady=5)
def toggle_camera(self):
if not self.camera_active:
# 启动摄像头
self.cap = cv2.VideoCapture(0)
if not self.cap.isOpened():
messagebox.showerror("错误", "无法访问摄像头!")
return
self.camera_active = True
self.start_btn.config(text="停止摄像头", bg="#e74c3c")
self.status_bar.config(text="摄像头已启动 - 正在检测人脸...")
self.update_camera()
else:
# 停止摄像头
self.camera_active = False
self.start_btn.config(text="启动摄像头", bg="#2ecc71")
if self.cap:
self.cap.release()
self.status_bar.config(text="摄像头已停止")
def update_camera(self):
if self.camera_active:
ret, frame = self.cap.read()
if ret:
# 转换颜色空间 BGR -> RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 进行人脸检测
gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
faces = self.face_cascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30)
)
# 更新人脸计数
self.face_count = len(faces)
if self.face_count > self.max_faces_detected:
self.max_faces_detected = self.face_count
# 在检测到的人脸周围画矩形
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 绘制人脸标签
cv2.putText(frame, f"Face", (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# 更新统计信息
self.face_count_label.config(text=f"检测到人脸: {self.face_count}")
self.max_face_label.config(text=f"最大同时检测数: {self.max_faces_detected}")
# 显示画面
img = Image.fromarray(frame)
img = img.resize((640, 480), Image.LANCZOS)
img_tk = ImageTk.PhotoImage(image=img)
self.camera_label.imgtk = img_tk
self.camera_label.configure(image=img_tk)
# 每10毫秒更新一次画面
self.root.after(10, self.update_camera)
def save_image(self):
if not self.camera_active:
messagebox.showwarning("警告", "请先启动摄像头!")
return
ret, frame = self.cap.read()
if ret:
# 保存当前帧
cv2.imwrite("captured_face.jpg", frame)
messagebox.showinfo("保存成功", "当前画面已保存为 'captured_face.jpg'")
self.status_bar.config(text="当前画面已保存为 captured_face.jpg")
def exit_app(self):
if self.camera_active:
self.camera_active = False
if self.cap:
self.cap.release()
self.root.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = FaceRecognitionApp(root)
root.mainloop()
运行说明
-
这个应用使用了OpenCV的人脸检测功能,基于Haar级联分类器
-
运行前需要安装以下Python库:
text
pip install opencv-python pillow
-
应用功能:
-
启动/停止摄像头
-
实时人脸检测并在画面中标记
-
显示检测到的人脸数量统计
-
保存当前摄像头画面
-
简洁易用的图形界面
-