项目背景
人脸识别技术已广泛应用于安全、社交和智能系统。本文将详细介绍如何使用Python构建一个简单yet实用的人脸识别桌面应用。
D:\spiderdocs\facedetectandrecongnize.py
技术选型
- OpenCV:图像处理与人脸检测
- wxPython:跨平台桌面GUI
- Python:编程语言
核心功能
- 添加已知人脸
- 批量导入人脸库
- 实时人脸识别
- 可视化识别结果
全部代码
import cv2
import numpy as np
import os
import wx
class FaceRecognizer:
def __init__(self):
# 使用OpenCV的Haar级联分类器
self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
self.known_faces = {}
def detect_faces(self, image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = self.face_cascade.detectMultiScale(gray, 1.1, 4)
return faces
def add_known_face(self, image, name):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = self.detect_faces(image)
if len(faces) > 0:
(x, y, w, h) = faces[0]
face_roi = gray[y:y+h, x:x+w]
self.known_faces[name] = face_roi
return True
return False
def recognize_face(self, image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = self.detect_faces(image)
results = []
for (x, y, w, h) in faces:
face_roi = gray[y:y+h, x:x+w]
name = "Unknown"
for known_name, known_face in self.known_faces.items():
# 简单的特征匹配
if self.compare_faces(face_roi, known_face):
name = known_name
break
results.append((name, (x, y, w, h)))
return results
def compare_faces(self, face1, face2, threshold=0.8):
# 使用模板匹配方法比较人脸
result = cv2.matchTemplate(face1, face2, cv2.TM_CCOEFF_NORMED)
return result[0][0] > threshold
class FaceRecognitionApp(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='人脸识别系统')
self.face_recognizer = FaceRecognizer()
panel = wx.Panel(self)
main_sizer = wx.BoxSizer(wx.VERTICAL)
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
add_face_btn = wx.Button(panel, label='添加人脸')
add_face_btn.Bind(wx.EVT_BUTTON, self.on_add_face)
btn_sizer.Add(add_face_btn, 0, wx.ALL, 5)
recognize_btn = wx.Button(panel, label='识别人脸')
recognize_btn.Bind(wx.EVT_BUTTON, self.on_recognize)
btn_sizer.Add(recognize_btn, 0, wx.ALL, 5)
# 批量添加按钮
batch_add_btn = wx.Button(panel, label='批量添加人脸')
batch_add_btn.Bind(wx.EVT_BUTTON, self.on_batch_add)
btn_sizer.Add(batch_add_btn, 0, wx.ALL, 5)
name_label = wx.StaticText(panel, label='姓名:')
self.name_input = wx.TextCtrl(panel)
self.result_text = wx.StaticText(panel, label='')
main_sizer.Add(btn_sizer, 0, wx.CENTER)
main_sizer.Add(name_label, 0, wx.ALL|wx.CENTER, 5)
main_sizer.Add(self.name_input, 0, wx.ALL|wx.CENTER, 5)
main_sizer.Add(self.result_text, 0, wx.ALL|wx.CENTER, 5)
panel.SetSizer(main_sizer)
main_sizer.Fit(self)
self.Center()
def on_add_face(self, event):
with wx.FileDialog(self, "选择图像",
wildcard="图像文件 (*.jpg;*.png)|*.jpg;*.png",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
return
pathname = fileDialog.GetPath()
name = self.name_input.GetValue().strip()
if not name:
wx.MessageBox('请输入姓名', '错误', wx.OK | wx.ICON_ERROR)
return
try:
image = cv2.imread(pathname)
if self.face_recognizer.add_known_face(image, name):
wx.MessageBox(f'{name} 的人脸已成功添加', '成功', wx.OK)
else:
wx.MessageBox('未检测到人脸', '错误', wx.OK | wx.ICON_ERROR)
except Exception as e:
wx.MessageBox(f'处理图像时出错: {str(e)}', '错误', wx.OK | wx.ICON_ERROR)
def on_batch_add(self, event):
with wx.DirDialog(self, "选择包含人脸图像的文件夹") as dirDialog:
if dirDialog.ShowModal() == wx.ID_CANCEL:
return
folder_path = dirDialog.GetPath()
name = self.name_input.GetValue().strip()
if not name:
wx.MessageBox('请输入姓名', '错误', wx.OK | wx.ICON_ERROR)
return
added_count = 0
total_count = 0
for filename in os.listdir(folder_path):
if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
total_count += 1
filepath = os.path.join(folder_path, filename)
try:
image = cv2.imread(filepath)
if self.face_recognizer.add_known_face(image, name):
added_count += 1
except Exception:
pass
wx.MessageBox(f'成功添加 {added_count}/{total_count} 张人脸', '批量添加结果', wx.OK)
def on_recognize(self, event):
with wx.FileDialog(self, "选择识别图像",
wildcard="图像文件 (*.jpg;*.png)|*.jpg;*.png",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
return
pathname = fileDialog.GetPath()
try:
image = cv2.imread(pathname)
image_copy = image.copy()
results = self.face_recognizer.recognize_face(image)
if results:
result_str = "识别结果:\n"
for name, (x, y, w, h) in results:
result_str += f"{name} "
# 在图像上绘制人脸框
cv2.rectangle(image_copy, (x, y), (x+w, y+h), (0, 255, 0), 2)
self.result_text.SetLabel(result_str)
# 显示带人脸框的图像
cv2.imshow('识别结果', image_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
self.result_text.SetLabel('未找到人脸')
except Exception as e:
wx.MessageBox(f'识别人脸时出错: {str(e)}', '错误', wx.OK | wx.ICON_ERROR)
def main():
app = wx.App()
frame = FaceRecognitionApp()
frame.Show()
app.MainLoop()
if __name__ == '__main__':
main()
关键代码解析
人脸检测核心算法
def detect_faces(self, image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = self.face_cascade.detectMultiScale(gray, 1.1, 4)
return faces
特征匹配机制
def compare_faces(self, face1, face2, threshold=0.8):
result = cv2.matchTemplate(face1, face2, cv2.TM_CCOEFF_NORMED)
return result[0][0] > threshold
项目亮点
- 低依赖:仅依赖OpenCV和wxPython
- 易扩展:可轻松添加更多识别算法
- 跨平台:支持Windows、Linux和macOS
实际应用场景
- 安防系统
- 智能考勤
- 个人相册管理
运行结果

2284

被折叠的 条评论
为什么被折叠?



