zdh
2025-07-29 bbf2ff2b0990349f142fed7fc8834eb40509024d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# -*- coding: utf-8 -*-
#'''文件修改说明
#-1、将手动增加类别改成通过json映射获取
#-2、识别结果和时间结合起来放一个日志里面,另外把识别的图片放同一个文件夹,最大500张
#   陌生人就用时间和识别失败结合起来,图片也放另一个文件夹,最大500张,多的就更新
#’‘’
 
 
import cv2
import sys
import gc
import time                       # 新增:用于获取当前时间
import os                         # 新增:用于文件和文件夹操作
import json                       #--------------------修改,新增导入
from keras_train import Model
#------------新增-------------
# 定义保存图片的文件夹路径
SUCCESS_FOLDER = 'recognized_images'
FAILURE_FOLDER = 'unrecognized_images'
# 定义日志文件路径
LOG_FILE = 'recognition_log.txt'
 
# 创建保存图片的文件夹(如果不存在)
if not os.path.exists(SUCCESS_FOLDER):
    os.makedirs(SUCCESS_FOLDER)
if not os.path.exists(FAILURE_FOLDER):
    os.makedirs(FAILURE_FOLDER)
#############################
 
if __name__ == '__main__':
    # if len(sys.argv) != 2:
    #     print("Usage:%s camera_id\r\n" % (0))
    #     sys.exit(0)
 
    # 加载模型
    model = Model()
    model.load_model(file_path='./model/me.face.model.h5')
 
    # 框住人脸的矩形边框颜色
    color = (0, 255, 0)
 
    # 捕获指定摄像头的实时视频流
    cap = cv2.VideoCapture(0)
 
    # 人脸识别分类器本地存储路径
    cascade_path = ".\\model\\haarcascade_frontalface_alt2.xml"
 
    #-------新增---------
    # 从 JSON 文件中加载类别映射,增加异常检测                                    -------------------修改部分,标注一
    try:
        with open('class_indices.json', 'r', encoding='utf-8') as file:
            class_indices = json.load(file)
        # 反转字典,以便通过索引查找类别名称
        human = {v: k for k, v in class_indices.items()}
        # 添加未知类别
        human[-1] = 'others'
    except FileNotFoundError:
        print("错误:未找到 class_indices.json 文件,请先运行训练脚本。")
        sys.exit(1)
 
    # 循环检测识别人脸
    while True:
        _, frame = cap.read()  # 读取一帧视频
 
        # 图像灰化,降低计算复杂度
        frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
        # 使用人脸识别分类器,读入分类器
        cascade = cv2.CascadeClassifier(cascade_path)
 
        # 利用分类器识别出哪个区域为人脸
        faceRects = cascade.detectMultiScale(frame_gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
        if len(faceRects) > 0:
            for faceRect in faceRects:
                x, y, w, h = faceRect
 
                # 截取脸部图像提交给模型识别这是谁
                image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
                # print("image:",image)
                faceID = model.face_predict(image)
 
                #------------------------新增--------------------------
                # 获取当前时间
                current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
 
                if faceID != -1:
                    # 识别成功
                    person_name = human[faceID]
                    log_message = f"{current_time}: 识别到 {person_name}"
                    save_folder = SUCCESS_FOLDER
                    image_name = f"{person_name}_{current_time.replace(':', '-')}.jpg"
                else:
                    # 识别失败
                    person_name = 'others'
                    log_message = f"{current_time}: 识别失败"
                    save_folder = FAILURE_FOLDER
                    image_name = f"recognition_failure_{current_time.replace(':', '-')}.jpg"
 
                # 记录日志
                with open(LOG_FILE, 'a', encoding='utf-8') as log_file:
                    log_file.write(log_message + '\n')
 
                # 保存图片
                image_path = os.path.join(save_folder, image_name)
                if image.size > 0:
                    cv2.imwrite(image_path, image)
 
                # 检查文件夹中图片数量是否超过 500 张
                image_files = [f for f in os.listdir(save_folder) if f.endswith('.jpg')]
                if len(image_files) > 500:
                    # 按修改时间排序
                    image_files.sort(key=lambda f: os.path.getmtime(os.path.join(save_folder, f)))
                    # 删除最旧的图片
                    os.remove(os.path.join(save_folder, image_files[0]))
                ###########################################
 
                # 如果是“我”                                                -------------修改成自动的,也就是标注一
                #human = {0:'me',1:'huangzong', 2:'xileizhao', -1:'others',3:'wumu',4:'songyunfei',
                #         5:'wuhuiting',6:'yangyang',7:'wm'}
 
 
                cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
 
                # 文字提示是谁
                cv2.putText(frame, human[faceID],
                            (x + 30, y + 30),  # 坐标
                            cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                            1,  # 字号
                            (255, 0, 255),  # 颜色
                            2)  # 字的线宽
 
 
        cv2.imshow("shi bie ren lian", frame)
 
        # 等待10毫秒看是否有按键输入
        k = cv2.waitKey(10)
        # 如果输入q则退出循环
        if k & 0xFF == ord('q'):
            break
 
    # 释放摄像头并销毁所有窗口
    cap.release()
    cv2.destroyAllWindows()