Delete 'renlian.py'

main
pxnmejity 9 months ago
parent f6fe468134
commit 05ca7fa4f9

@ -1,522 +0,0 @@
import cv2
import numpy as np
import os
import shutil
import threading
import tkinter as tk
from PIL import Image, ImageTk
import jiqiren as jqr
import yuyin as yy
import MySQL as m
import time
# 首先读取config文件第一行代表当前已经储存的人名个数接下来每一行是idname标签和对应的人名
id_dict = {} # 字典里存的是id——name键值对
Total_face_num = 999 # 已经被识别有用户名的人脸个数,
def init(): # 将config文件内的信息读入到字典中
global Total_face_num
Total_face_num = m.rl_select('count(name)')[0][0]
def begin():
init()
# 加载OpenCV人脸检测分类器Haar
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
# 准备好识别方法LBPH方法
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 打开标号为0的摄像头
camera = cv2.VideoCapture(0) # 摄像头
success, img = camera.read() # 从摄像头读取照片
W_size = 0.1 * camera.get(3)
H_size = 0.1 * camera.get(4)
system_state_lock = 0 # 标志系统状态的量 0表示无子线程在运行 1表示正在刷脸 2表示正在录入新面孔。
# 相当于mutex锁用于线程同步
a = (face_cascade, recognizer, success, W_size, H_size, system_state_lock, camera)
return a
'''
============================================================================================
以上是初始化
============================================================================================
'''
def Get_new_face(a):
# a = (face_cascade, recognizer, success, W_size, H_size, system_state_lock ,camera)
face_cascade = a[0]
recognizer = a[1]
W_size = a[3]
H_size = a[4]
camera = a[6]
jqr.Key("请对该面部信息进行命名:")
yy.record()
name = yy.asr_updata()
l = len(name)
name = name[0: l-1]
print("正在从摄像头录入新人脸信息 \n")
# 存在目录data就清空不存在就创建确保最后存在空的data目录
filepath = "data"
if not os.path.exists(filepath):
os.mkdir(filepath)
else:
shutil.rmtree(filepath)
os.mkdir(filepath)
sample_num = 0 # 已经获得的样本数
while True: # 从摄像头读取图片
global success
global img # 因为要显示在可视化的控件内,所以要用全局的
success, img = camera.read()
cv2.imshow("capture", img) # 生成摄像头窗口
# 转为灰度图片
if success is True:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
return name
# 检测人脸将每一帧摄像头记录的数据带入OpenCv中让Classifier判断人脸
# 其中gray为要检测的灰度图像1.3为每次图像尺寸减小的比例5为minNeighbors
face_detector = face_cascade
faces = face_detector.detectMultiScale(gray, 1.3, 5)
# 框选人脸for循环保证一个能检测的实时动态视频流
for (x, y, w, h) in faces:
# xy为左上角的坐标,w为宽h为高用rectangle为人脸标记画框
cv2.rectangle(img, (x, y), (x + w, y + w), (255, 0, 0))
# 样本数加1
sample_num += 1
# 保存图像把灰度图片看成二维数组来检测人脸区域这里是保存在data缓冲文件夹内
T = Total_face_num
cv2.imwrite("./data/User." + str(T) + '.' + str(sample_num) + '.jpg', gray[y:y + h, x:x + w])
pictur_num = 30 # 表示摄像头拍摄取样的数量,越多效果越好,但获取以及训练的越慢
cv2.waitKey(1)
if sample_num > pictur_num:
return name
else: # 控制台内输出进度条
l = int(sample_num / pictur_num * 50)
r = int((pictur_num - sample_num) / pictur_num * 50)
print("\r" + "%{:.1f}".format(sample_num / pictur_num * 100) + "=" * l + "->" + "_" * r, end="")
# var.set("%{:.1f}".format(sample_num / pictur_num * 100)) # 控件可视化进度信息
# tk.Tk().update()
# window.update() # 刷新控件以实时显示进度
def Train_new_face():
print("\n正在训练")
# cv2.destroyAllWindows()
path = 'data'
# 初始化识别的方法
recog = cv2.face.LBPHFaceRecognizer_create()
# 调用函数并将数据喂给识别器训练
faces, ids = get_images_and_labels(path)
print('本次用于训练的识别码为:') # 调试信息
print(ids) # 输出识别码
# 训练模型 #将输入的所有图片转成四维数组
recog.train(faces, np.array(ids))
# 保存模型
yml ='/home/cxg/BYSJ/RL-data/' + str(Total_face_num) + ".yml"
print(yml)
rec_f = open(yml, "w+")
rec_f.close()
recog.save(yml)
# recog.save('aaa.yml')
# 创建一个函数,用于从数据集文件夹中获取训练图片,并获取id
# 注意图片的命名格式为User.id.sampleNum
def get_images_and_labels(path):
image_paths = [os.path.join(path, f) for f in os.listdir(path)]
# 新建连个list用于存放
face_samples = []
ids = []
# 遍历图片路径导入图片和id添加到list中
for image_path in image_paths:
# 通过图片路径将其转换为灰度图片
img = Image.open(image_path).convert('L')
# 将图片转化为数组
img_np = np.array(img, 'uint8')
if os.path.split(image_path)[-1].split(".")[-1] != 'jpg':
continue
# 为了获取id将图片和路径分裂并获取
id = int(os.path.split(image_path)[-1].split(".")[1])
# 调用熟悉的人脸分类器
detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
faces = detector.detectMultiScale(img_np)
# 将获取的图片和id添加到list中
for (x, y, w, h) in faces:
face_samples.append(img_np[y:y + h, x:x + w])
ids.append(id)
return face_samples, ids
def write_config(name):
print("新人脸训练结束")
T = Total_face_num
m.rl_insert(str(T),name,)
jqr.Key("是否要设置其他个人信息?")
text = yy.record_text()
if ("" in text):
information_update(str(T), "年龄")
information_update(str(T), "性别")
information_update(str(T), "电话号码")
information_update(str(T), "生日")
jqr.Key("完成录入信息")
'''
============================================================================================
以上是录入新人脸信息功能的实现
============================================================================================
'''
def scan_face(a):
# 使用之前训练好的模型
# a = (face_cascade, recognizer, success, W_size, H_size, system_state_lock ,camera)
face_cascade = a[0]
recognizer = a[1]
W_size = a[3]
H_size = a[4]
camera = a[6]
for i in range(Total_face_num): # 每个识别器都要用
i += 1
yml ='/home/cxg/BYSJ/RL-data/' + str(i) + ".yml"
print("\n本次:" + yml) # 调试信息
recognizer.read(yml)
ave_poss = 0
for times in range(10): # 每个识别器扫描十遍
times += 1
cur_poss = 0
global success
global img
'''
global system_state_lock
while system_state_lock == 2: # 如果正在录入新面孔就阻塞
print("\r刷脸被录入面容阻塞", end="")
pass
'''
success, img = camera.read()
cv2.imshow("capture", img) # 生成摄像头窗口
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 识别人脸
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(int(W_size), int(H_size))
)
# 进行校验
for (x, y, w, h) in faces:
'''
global system_state_lock
while system_state_lock == 2: # 如果正在录入新面孔就阻塞
print("\r刷脸被录入面容阻塞", end="")
pass
'''
# 这里调用Cv2中的rectangle函数 在人脸周围画一个矩形
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 调用分类器的预测函数,接收返回值标签和置信度
idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])
conf = confidence
# 计算出一个检验结果
if confidence < 100: # 可以识别出已经训练的对象——直接输出姓名在屏幕上
if idnum in id_dict:
user_name = id_dict[idnum]
else:
# print("无法识别的ID:{}\t".format(idnum), end="")
user_name = "Untagged user:" + str(idnum)
confidence = "{0}%", format(round(100 - confidence))
else: # 无法识别此对象,那么就开始训练
user_name = "unknown"
# print("检测到陌生人脸\n")
# cv2.destroyAllWindows()
# global Total_face_num
# Total_face_num += 1
# Get_new_face() # 采集新人脸
# Train_new_face() # 训练采集到的新人脸
# write_config() # 修改配置文件
# recognizer.read('aaa.yml') # 读取新识别器
# 加载一个字体用于输出识别对象的信息
font = cv2.FONT_HERSHEY_SIMPLEX
# 输出检验结果以及用户名
cv2.putText(img, str(user_name), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (0, 0, 0), 1)
# 展示结果
# cv2.imshow('camera', img)
print("conf=" + str(conf), end="\t")
if 35 > conf > 0:
cur_poss = 1 # 表示可以识别
elif 75 > conf > 35:
cur_poss = 1 # 表示可以识别
else:
cur_poss = 0 # 表示不可以识别
k = cv2.waitKey(1)
if k == 27:
# cam.release() # 释放资源
cv2.destroyAllWindows()
break
ave_poss += cur_poss
if ave_poss >= 5: # 有一半以上识别说明可行则返回
return i
return 0 # 全部过一遍还没识别出说明无法识别
'''
============================================================================================
以上是关于刷脸功能的设计
============================================================================================
'''
def information_update(T, str):
if ("生日" in str):
birthday_update(T)
elif (str in "年龄,性别,姓名,电话"):
jqr.Key("该用户"+str+"为:")
str = change(str)
text = yy.record_text()
text = text[0: len(text) - 1]
# print(text,T)
m.rl_update(T, str, text)
def birthday_update(T):
message = ['','','']
jqr.Key("该用户出生年份为:")
text = yy.record_text()
message[0] = text[0: len(text) - 1]
jqr.Key("该用户出生月份为:")
text = yy.record_text()
message[1] = text[0: len(text) - 1]
jqr.Key("该用户出生日期为:")
text = yy.record_text()
message[2] = text[0: len(text) - 1]
m.rl_update(str(T), "birthday", str(message[0]) + "-" + str(message[1]) + "-" + str(message[2]))
def change(str):
if ("姓名" in str):
return "name"
elif ("年龄" in str):
return "age"
elif ("性别" in str):
return "sex"
elif ("电话" in str):
return "phone"
def rl_message_update(id):
while True:
jqr.Key("需要修改什么信息?")
text = yy.record_text()
if ("取消" in text):
break
elif (text not in ""):
text = text[0: len(text) - 1]
information_update(id, text)
'''
============================================================================================
以上是修改人脸信息功能的实现
============================================================================================
'''
def f_scan_face():
# 使用之前训练好的模型
# recognizer.read('aaa.yml')
# var.set('刷脸')
a = begin() #申请摄像头资源
ans = scan_face(a)
if ans == 0:
# print("最终结果:无法识别")
# var.set("最终结果:无法识别")
jqr.Key("人脸识别完毕。最终结果:检测失败")
cv2.destroyAllWindows()
a[6].release()
return 0,0
else:
id_dict = m.rl_select('id')
name_dict = m.rl_select("name")
ans_name = "最终结果User" + str(id_dict[ans-1][0]) + name_dict[ans-1][0]
# print(ans_name)
# var.set(ans_name)
jqr.Key("人脸识别完毕。"+ ans_name)
jqr.Key("人脸检测成功。。。")
cv2.destroyAllWindows()
a[6].release()
return 1,str(id_dict[ans-1][0])
def f_rec_face():
a = begin() #申请摄像头资源
# var.set('录入')
global Total_face_num
Total_face_num += 1
name = Get_new_face(a) # 采集新人脸
print("采集完毕,开始训练")
jqr.Key("人脸录入完毕。")
global system_state_lock # 采集完就可以解开锁
# print("锁被释放0")
system_state_lock = 0
Train_new_face() # 训练采集到的新人脸
write_config(name) # 修改数据库
cv2.destroyAllWindows()
a[6].release()
# recognizer.read('aaa.yml') # 读取新识别器
# global system_state_lock
# print("锁被释放0")
# system_state_lock = 0 # 修改system_state_lock,释放资源
def check_face():
while True:
jqr.Key("即将进行人脸检测。。。。")
sign = f_scan_face()
# print(sign)
if(0 in sign):
jqr.Key("人脸检测失败,是否要重新检测。。。")
yy.record()
text = yy.asr_updata()
print("本人说:", text)
if("" in text or "重新检测" in text):
continue
elif("" in text or "取消" in text):
return 0
else:
jqr.Key("未检测到关键字!将继续进行人脸检测。。。")
continue
else:
return sign[1]
'''
============================================================================================
以上是关于人脸的执行设计
============================================================================================
'''
def manual_video(): #视频监控
camera = cv2.VideoCapture(0) # 摄像头
print('开始视频监控')
id = m.hcsr_select("m_photo", "max(num_id)")[0][0] + 1 # 确认操作编号
t = time.strftime('%Y-%m-%d %H:%M:%S')
photoname = m.hcsr_select("m_photo", "max(last_photo)")[0][0] + 1 # 文件名序号初始值
temp = photoname # 记录第一张照片的临时变量
m.hcsr_insert("m_photo", str(id), t, str(photoname)) # 保存数据
while True:
# get a frame
ret, frame = camera.read()
frame = cv2.flip(frame, 1) # 摄像头是和人对立的,将图像左右调换回来正常显示
# show a frame
cv2.imshow("capture", frame) # 生成摄像头窗口
if cv2.waitKey(1) & 0xFF == ord('q'): # 如果按下q 就截图保存并退出
cv2.imwrite('/home/cxg/BYSJ/manual-photo/' +"m_video" + str(photoname) + ".png", frame) # 保存路径
cv2.destroyAllWindows()
m.hcsr_update("m_photo", "last_photo", str(photoname), str(id)) # 保存最后一张照片的数据
m.hcsr_update("m_photo", "num", str(photoname - temp + 1), str(id))
break
elif cv2.waitKey(1) & 0xFF == ord('z'):
cv2.imwrite('/home/cxg/BYSJ/manual-photo/' +"m_video" + str(photoname) + ".png", frame) # 保存路径
m.hcsr_update("m_photo", "last_photo", str(photoname), str(id)) # 保存最后一张照片的数据
m.hcsr_update("m_photo", "num", str(photoname - temp + 1), str(id))
photoname += 1
continue
camera.release()
def auto_video(): #自动监控
camera = cv2.VideoCapture(0) # 摄像头
print('开始自动监控')
i = 0 # 定时装置初始值
id = m.hcsr_select("hcsr", "max(num_id)")[0][0] + 1 #确认操作编号
t = time.strftime('%Y-%m-%d %H:%M:%S')
photoname = m.hcsr_select("hcsr", "max(last_photo)")[0][0] + 1 # 文件名序号初始值
temp = photoname #记录第一张照片的临时变量
m.hcsr_insert("hcsr", str(id), t, str(photoname)) #保存数据
while True:
i = i + 1 #计时
reg, frame = camera.read()
frame = cv2.flip(frame, 1) # 图片左右调换
cv2.imshow('window', frame)
if i == 50: # 定时装置,定时截屏,可以修改。
filename = "a_video" + str(photoname) + '.png' # filename为图像名字将photoname作为编号命名保存的截图
cv2.imwrite('/home/cxg/BYSJ/aut-photo/' + filename, frame) # 截图 前面为放在桌面的路径 frame为此时的图像
print(filename + '保存成功') # 打印保存成功
i = 0 # 清零
m.hcsr_update("hcsr", "last_photo", str(photoname), str(id)) #保存最后一张照片的数据
m.hcsr_update("hcsr", "num", str(photoname - temp+1), str(id))
photoname += 1
if photoname - temp >= 20: # 最多截图20张 然后退出如果调用photoname = 1 不用break为不断覆盖图片
# photoname = 1
cv2.destroyAllWindows()
# 释放资源
camera.release()
return str(id),1
if cv2.waitKey(1) & 0xff == ord('q'):
cv2.destroyAllWindows()
# 释放资源
camera.release()
return str(id),0
cv2.destroyAllWindows()
# 释放资源
camera.release()
'''
============================================================================================
以上是关于监控的设计
============================================================================================
'''
Loading…
Cancel
Save