# -*- 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()
|