代码拉取完成,页面将自动刷新
import cv2
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import numpy as np
import os
def face_gui():
root = tk.Tk()
root.title("人脸识别系统软件")
root.iconbitmap("face.ico")
root.geometry("850x500")
#加载训练数据集文件
recogizer=cv2.face.LBPHFaceRecognizer_create()
recogizer.read('trainer/trainer.yml')
#图片路径
global path
path='./data/'
camera_port = tk.StringVar()
camera_port.set("2") # 设置默认相机端口为0
resolution = tk.StringVar()
resolution.set("720p") # 设置默认分辨率为480p
haarcascade = tk.StringVar()
haarcascade.set("models/haarcascade_frontalface_default.xml") # 设置默认haarcascade模型
# 创建选项卡式窗口
notebook = ttk.Notebook(root)
notebook.pack(fill='both', expand=True)
# 创建人脸识别界面
camera_page = ttk.Frame(notebook)
notebook.add(camera_page, text="人脸识别界面")
# 创建图像显示区域
canvas = tk.Canvas(camera_page,height=300,width=800)
canvas.grid(row=5, column=0, rowspan=1, columnspan=6)
color_label = tk.Label(canvas)
depth_label = tk.Label(canvas)
canvas.create_rectangle(2, 2, 399, 299)
canvas.create_rectangle(400, 2, 799, 299)
canvas.create_window(200, 150, window=color_label)
canvas.create_window(600, 150, window=depth_label)
def open_camera():
# 从相机读取图像
global cap
camera_ports = camera_port.get()
if camera_ports == "":
camera_ports = 0 # 如果相机端口为空字符串,则设置为默认端口0
else:
camera_ports = int(camera_ports)
cap = cv2.VideoCapture(camera_ports)
resolutions = resolution.get()
match resolutions:
case "720p":
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 768)
case "480p":
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
case "360p":
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
ret, frame = cap.read()
try:
while ret:
ret, frame = cap.read()
# 在图像上进行人脸检测
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cascade = cv2.CascadeClassifier(haarcascade.get())
faces = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
current_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pil_current_image = Image.fromarray(current_image)
# 在图像上绘制人脸框并显示
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 将OpenCV图像转换为PIL图像
face_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pil_face_image = Image.fromarray(face_image)
# 将PIL图像转换为Tkinter图像
tk_current_image = ImageTk.PhotoImage(pil_current_image.resize((380, 285)))
tk_face_image = ImageTk.PhotoImage(pil_face_image.resize((380, 285)))
# 更新图像显示
color_label.config(image=tk_current_image)
depth_label.config(image=tk_face_image)
# 保持图像显示的引用,防止被垃圾回收
color_label.image = pil_current_image
depth_label.image = pil_face_image
# 每隔100毫秒更新图像显示
camera_page.update()
finally:
cap.release()
# 创建保存图像函数
def save_image(color_image):
# 创建data文件夹(如果不存在)
if not os.path.exists("data"):
os.makedirs("data")
# 获取data文件夹下已保存图像的数量
# num_files = len(os.listdir("data"))
# 获取data文件夹下最大的序号
num_files = 0
for file_name in os.listdir("./data"):
if file_name.endswith(".png"):
index = int(file_name.split(".")[0])
num_files = max(num_files, index)
# 保存彩色图为PNG格式
color_image_path = "data/{:04d}.png".format(num_files + 1)
color_image.save(color_image_path)
print(f"Color image saved as {color_image_path}")
def save_button_callback():
# 获取当前显示的彩色图和深度图
color_image = color_label.image
# 保存当前图像
if color_image is not None:
save_image(color_image)
else:
print("No image to save")
def close_camera():
# camera_static = 1
cap.release()
# 创建相机端口选择菜单
camera_label = tk.Label(camera_page, text="相机 端口:")
camera_label.grid(row=1, column=1)
camera_menu = ttk.Combobox(camera_page, textvariable=camera_port, value=("0", "1", "2"))
camera_menu.configure(width=100)
camera_menu.grid(row=1, column=3, columnspan=1)
# 创建分辨率选择菜单
resolution_label = tk.Label(camera_page, text="图像分辨率:")
resolution_label.grid(row=2, column=1)
resolution_menu = ttk.Combobox(camera_page, textvariable=resolution, value=("720p", "480p", "360p"))
resolution_menu.configure(width=100)
resolution_menu.grid(row=2, column=3, columnspan=1)
# 创建haarcascade模型选择菜单
haarcascade_label = tk.Label(camera_page, text="Haar 模型:")
haarcascade_label.grid(row=3, column=1)
haarcascade_menu = ttk.Combobox(camera_page, textvariable=haarcascade, value=("models/haarcascade_frontalface_alt.xml", "models/haarcascade_frontalface_alt2.xml", "models/haarcascade_frontalface_default.xml"))
haarcascade_menu.configure(width=100)
haarcascade_menu.grid(row=3, column=3, columnspan=1)
# 创建打开相机按钮
open_button = tk.Button(camera_page, text="打开相机", command=open_camera, bg='green',fg='yellow')
open_button.grid(row=4, column=1)
# 创建关闭相机按钮
close_button = tk.Button(camera_page, text="关闭相机", command=close_camera, bg='red',fg='yellow')
close_button.grid(row=4, column=3)
# 创建保存图像按钮
save_button = tk.Button(camera_page, text="保存图像", command=save_button_callback, bg='blue',fg='yellow')
save_button.grid(row=4, column=5)
la2=tk.Label(camera_page,text='原始图像')
la2.grid(row=6,column=1) # 0行0列
la2=tk.Label(camera_page,text='识别图像')
la2.grid(row=6,column=5) # 0行0列
# 创建人脸登记界面
model_page = ttk.Frame(notebook)
notebook.add(model_page, text="人脸登记界面")
# 创建图像显示区域
canvas1 = tk.Canvas(model_page,height=300,width=800)
canvas1.grid(row=5, column=0, rowspan=1, columnspan=6)
color_label1 = tk.Label(canvas1)
depth_label1 = tk.Label(canvas1)
canvas1.create_rectangle(2, 2, 399, 299)
canvas1.create_rectangle(400, 2, 799, 299)
canvas1.create_window(200, 150, window=color_label1)
canvas1.create_window(600, 150, window=depth_label1)
def open_camera1():
# 从相机读取图像
# cap.release()
global cap1
camera_ports = camera_port.get()
if camera_ports == "":
camera_ports = 0 # 如果相机端口为空字符串,则设置为默认端口0
else:
camera_ports = int(camera_ports)
cap1 = cv2.VideoCapture(camera_ports)
cap1.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
cap1.set(cv2.CAP_PROP_FRAME_HEIGHT, 768)
ret, frame = cap1.read()
try:
while ret:
ret, frame = cap1.read()
current_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pil_current_image = Image.fromarray(current_image)
# 将PIL图像转换为Tkinter图像
tk_current_image = ImageTk.PhotoImage(pil_current_image.resize((380, 285)))
# 更新图像显示
color_label1.config(image=tk_current_image)
# 保持图像显示的引用,防止被垃圾回收
color_label1.image = pil_current_image
# 每隔100毫秒更新图像显示
model_page.update()
finally:
cap1.release()
# 创建保存图像函数
def save_name_image():
ret_flag,Vshow = cap1.read()#得到每帧图像
# 创建data文件夹(如果不存在)
if not os.path.exists("data"):
os.makedirs("data")
# 获取data文件夹下已保存图像的数量
# num_files = len(os.listdir("data"))
# 获取data文件夹下最大的序号
num_files = 0
for file_name in os.listdir("./data"):
if file_name.endswith(".jpg"):
index = int(file_name.split(".")[0])
num_files = max(num_files, index)
# 保存彩色图为PNG格式
cv2.imwrite("data/"+str(num_files + 1)+"."+ a_entry.get() +".jpg",Vshow)
print("success to save"+str(num_files + 1)+".jpg")
print("-------------------")
# 创建相机端口选择菜单
def getImageAndLabels(path):
facesSamples=[]
ids=[]
imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
#检测人脸
face_detector = cv2.CascadeClassifier('models/haarcascade_frontalface_alt2.xml')
#打印数组imagePaths
print('数据排列:',imagePaths)
#遍历列表中的图片
for imagePath in imagePaths:
#打开图片,黑白化
PIL_img=Image.open(imagePath).convert('L')
#将图像转换为数组,以黑白深浅
# PIL_img = cv2.resize(PIL_img, dsize=(400, 400))
img_numpy=np.array(PIL_img,'uint8')
#获取图片人脸特征
faces = face_detector.detectMultiScale(img_numpy)
#获取每张图片的id和姓名
id = int(os.path.split(imagePath)[1].split('.')[0])
#预防无面容照片
for x,y,w,h in faces:
ids.append(id)
facesSamples.append(img_numpy[y:y+h,x:x+w])
#打印脸部特征和id
#print('fs:', facesSamples)
print('id:', id)
#print('fs:', facesSamples[id])
print('fs:', facesSamples)
#print('脸部例子:',facesSamples[0])
#print('身份信息:',ids[0])
return facesSamples,ids
def train_face():
#获取图像数组和id标签数组和姓名
faces,ids=getImageAndLabels(path)
#获取训练对象
recognizer=cv2.face.LBPHFaceRecognizer_create()
#recognizer.train(faces,names)#np.array(ids)
recognizer.train(faces,np.array(ids))
#保存文件
recognizer.write('trainer/trainer.yml')
#准备识别的图片
def face_detect_demo():
# 从相机读取图像
global cap1
camera_ports = camera_port.get()
if camera_ports == "":
camera_ports = 0 # 如果相机端口为空字符串,则设置为默认端口0
else:
camera_ports = int(camera_ports)
cap1 = cv2.VideoCapture(camera_ports)
names = name()
cap1.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
cap1.set(cv2.CAP_PROP_FRAME_HEIGHT, 768)
ret, frame = cap1.read()
try:
while ret:
ret, frame = cap1.read()
# 在图像上进行人脸检测
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
current_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pil_current_image = Image.fromarray(current_image)
face_detector=cv2.CascadeClassifier('models/haarcascade_frontalface_alt2.xml')
face=face_detector.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(100,100),(300,300))
#face=face_detector.detectMultiScale(gray)
global warningtime
warningtime = 0
for x,y,w,h in face:
cv2.rectangle(frame,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)
cv2.circle(frame,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1)
# 人脸识别
ids, confidence = recogizer.predict(gray[y:y + h, x:x + w])
#print('标签id:',ids,'置信评分:', confidence)
if confidence > 80:
warningtime += 1
if warningtime > 100:
# warning()
warningtime = 0
cv2.putText(frame, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
else:
cv2.putText(frame,str(names[ids-1]+"{:.1f}".format(confidence)), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
# 将OpenCV图像转换为PIL图像
face_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pil_face_image = Image.fromarray(face_image)
# 将PIL图像转换为Tkinter图像
tk_current_image = ImageTk.PhotoImage(pil_current_image.resize((380, 285)))
tk_face_image = ImageTk.PhotoImage(pil_face_image.resize((380, 285)))
# 更新图像显示
color_label1.config(image=tk_current_image)
depth_label1.config(image=tk_face_image)
# 保持图像显示的引用,防止被垃圾回收
color_label1.image = pil_current_image
depth_label1.image = pil_face_image
# 每隔100毫秒更新图像显示
camera_page.update()
finally:
cap1.release()
def name():
names=[]
imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
for imagePath in imagePaths:
name = str(os.path.split(imagePath)[1].split('.',2)[1])
names.append(name)
return names
def close_camera1():
cap1.release()
camera_label = tk.Label(model_page, text="相机 端口:")
camera_label.grid(row=1, column=1)
camera_menu = ttk.Combobox(model_page, textvariable=camera_port, value=("0", "1", "2"))
camera_menu.configure(width=50)
camera_menu.grid(row=1, column=3, columnspan=1)
addr = tk.StringVar(value='lp')
a_label = tk.Label(model_page, text = "⽤户名:")
a_label.grid(row = 2, column = 1)
a_entry = tk.Entry(model_page, textvariable=addr)
a_entry.grid(row = 2, column = 3)
# 创建打开相机按钮
open1_button = tk.Button(model_page, text="打开相机", command=open_camera1, bg='green',fg='yellow')
open1_button.grid(row=4, column=2)
# 创建关闭相机按钮
close_button = tk.Button(model_page, text="关闭相机", command=close_camera1, bg='red',fg='yellow')
close_button.grid(row=4, column=3)
# 创建保存图像按钮
save_button = tk.Button(model_page, text="保存图像", command=save_name_image, bg='blue',fg='yellow')
save_button.grid(row=4, column=4)
# 创建训练特定人脸按钮
train_button = tk.Button(model_page, text="训练特定人脸", command=train_face, bg='red',fg='yellow')
train_button.grid(row=6, column=2)
# 创建识别特定人脸按钮
train_button = tk.Button(model_page, text="识别特定人脸", command=face_detect_demo, bg='red',fg='yellow')
train_button.grid(row=6, column=4)
# # 创建更新人脸数据表格按钮
# update_button = tk.Button(model_page, text="更新人脸数据表格", command=update_excel, bg='blue',fg='yellow')
# update_button.grid(row=6, column=4)
# 创建人脸数据界面
face_data_page = ttk.Frame(notebook)
notebook.add(face_data_page, text="人脸数据界面")
tree = ttk.Treeview(face_data_page) # #创建表格对象
# canvas1.create_window(600, 150, window=tree)
tree["columns"] = ("序号","姓名", "数量") # #定义列
tree.column("序号", width=80) # #设置列
tree.column("姓名", width=80)
tree.column("数量", width=80)
tree.heading("序号", text="x序号")
tree.heading("姓名", text="x姓名") # #设置显示的表头名
tree.heading("数量", text="x数量")
names = name()
# imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
# for imagePath in imagePaths:
# name = str(os.path.split(imagePath)[1].split('.',2)[1])
# names.append(name)
names = list(set(names))#去重
number = 0
for i in range(0,len(names)):
for file in os.listdir(path):
if file.endswith(str(names[i]+".jpg")):
number += 1 # 统计当前文件夹下csv类型文件的总数
tree.insert("", 0, text="line"+str(i), values=(str(i+1), names[i], str(number)))
i = i + 1
number = 0
tree.grid()
# 创建拍照保存按钮
button_frame = ttk.Frame(root)
button_frame.pack(side='bottom', fill='x')
quit_button = ttk.Button(button_frame, text="Quit", command=root.quit)
quit_button.pack(side='right', padx=5, pady=5)
root.mainloop()
if __name__ == '__main__':
face_gui()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。