测试帖子2
2025-08-07 18:01:52
发布于:浙江
这个文件夹在人脸识别中!
photo文件
import cv2
import numpy as np
from PIL import Image, ImageDraw
import tkinter as tk
from threading import Thread, Event
import queue
import time
class FaceDetectorApp:
def __init__(self):
# 初始化人脸检测器
self.face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
# 线程控制和数据共享
self.camera_running = Event()
self.camera_running.set()
self.frame_queue = queue.Queue(maxsize=5) # 原始帧队列
# 检测参数优化
self.detect_interval = 3 # 每3帧检测一次人脸
self.face_tracker = {} # 人脸跟踪器
self.track_id = 0 # 跟踪ID计数器
def run_camera(self):
"""运行摄像头捕获和人脸检测线程"""
cap = cv2.VideoCapture("rtsp://192.168.1.120:8554/test")
# 降低分辨率以提高性能
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
frame_count = 0
while self.camera_running.is_set():
ret, frame = cap.read()
if not ret:
break
# 保存原始帧用于截图
try:
self.frame_queue.put(frame, block=False)
except queue.Full:
self.frame_queue.get()
self.frame_queue.put(frame, block=False)
# 人脸检测优化:隔帧检测
frame_count += 1
if frame_count % self.detect_interval == 0:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 优化检测参数
faces = self.face_cascade.detectMultiScale(
gray,
scaleFactor=1.2, # 稍大的缩放因子,提高速度
minNeighbors=5, # 平衡误检和漏检
#minSize=(40, 40), # 忽略过小的人脸
#flags=cv2.CASCADE_SCALE_IMAGE
)
# 更新人脸跟踪信息
self.update_face_tracking(faces)
# 绘制人脸框(使用跟踪结果,保持框的连续性)
display_frame = frame.copy()
for face_data in self.face_tracker.values():
x, y, w, h = face_data['box']
cv2.rectangle(display_frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('RTSP Stream', display_frame)
if cv2.waitKey(1) == 27: # ESC键退出
break
cap.release()
cv2.destroyAllWindows()
def update_face_tracking(self, faces):
"""更新人脸跟踪信息,保持检测框的连续性"""
current_faces = [(x, y, w, h) for (x, y, w, h) in faces]
matched_ids = []
# 匹配现有跟踪ID
for face in current_faces:
x, y, w, h = face
center_x, center_y = x + w//2, y + h//2
best_match = None
min_distance = float('inf')
# 寻找最接近的历史人脸
for track_id, data in self.face_tracker.items():
if track_id in matched_ids:
continue
tx, ty, tw, th = data['box']
t_center_x, t_center_y = tx + tw//2, ty + th//2
# 计算中心距离
distance = np.sqrt((center_x - t_center_x)** 2 + (center_y - t_center_y)**2)
# 如果距离小于阈值且尺寸相近,认为是同一人脸
if distance < max(w, h) * 0.5 and distance < min_distance:
min_distance = distance
best_match = track_id
# 更新匹配的人脸信息
if best_match is not None:
self.face_tracker[best_match]['box'] = face
self.face_tracker[best_match]['age'] = 0 # 重置消失计时器
matched_ids.append(best_match)
else:
# 创建新跟踪ID
self.track_id += 1
self.face_tracker[self.track_id] = {
'box': face,
'age': 0 # 记录未被检测到的帧数
}
# 增加未匹配人脸的消失计时器
for track_id in list(self.face_tracker.keys()):
if track_id not in matched_ids:
self.face_tracker[track_id]['age'] += 1
# 如果连续多帧未检测到,移除跟踪
if self.face_tracker[track_id]['age'] > 5:
del self.face_tracker[track_id]
def take_screenshot(self):
"""截取当前画面并保存"""
try:
frame = self.frame_queue.get(block=False)
if frame is not None:
# 转换为PIL图像
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pil_img = Image.fromarray(rgb_frame)
draw = ImageDraw.Draw(pil_img)
# 保存截图
pil_img.save("screenshot.png", "PNG")
print("截图已保存为 screenshot.png")
return True
except queue.Empty:
print("无可用画面")
return False
def start_gui(self):
"""启动Tkinter图形界面"""
root = tk.Tk()
root.title("机械狗人脸检测系统")
root.geometry("400x200")
# 拍照按钮
btn_capture = tk.Button(
root, text="拍照", font=("Arial", 14),
command=self.take_screenshot
)
btn_capture.pack(padx=20, pady=20)
# 退出按钮
btn_quit = tk.Button(
root, text="退出", font=("Arial", 14),
command=lambda: [self.camera_running.clear(), root.destroy()]
)
btn_quit.pack(padx=20, pady=10)
# 窗口关闭时的处理
root.protocol("WM_DELETE_WINDOW", lambda: [self.camera_running.clear(), root.destroy()])
root.mainloop()
if __name__ == "__main__":
app = FaceDetectorApp()
# 启动摄像头线程
camera_thread = Thread(target=app.run_camera, daemon=True)
camera_thread.start()
# 启动GUI线程
app.start_gui()
haarcascade_frontalface_default文件
[haarcascade_frontalface_default文件](file:///C:/Users/Administrator/Desktop/0804%E7%B4%A0%E6%9D%90/AI%E4%BA%BA%E8%84%B8%E5%AF%B9%E6%AF%94%E5%AD%A6%E7%94%9F%E7%B4%A0%E6%9D%90/%E6%9C%BA%E5%99%A8%E7%8B%97%E6%8B%8D%E6%91%84%E7%85%A7%E7%89%87%E5%92%8C%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB/haarcascade_frontalface_default.xml)
人脸识别操作说明:
首先按F5运行main程序,在弹出的界面中输入第一个要对比的图片的名称及后缀名称(如man1.jpg),按下空格,再输入第二个要对比的图片的名称及后缀名称,最后按下空格,完成图片相似度输出。
这里空空如也
有帮助,赞一个