目录
运行结果
导入我们需要的包
from tkinter import filedialog
import cv2
from PIL import Image, ImageTk
from tkinter import messagebox
import subprocess
实例化窗口定义大小名字
win = tk.Tk()
win.title("人脸提取")
win.geometry("1500x800")
创建标签来显示图像
跟之前一样,我们依然创建两个标签,这里抓取的人脸显示标签我们需要一个滚动条,因为一张图像可能会有多张人脸
# 原始图片的标签
image_label_original = tk.Label(win)
image_label_original.pack(side=tk.LEFT, padx=10, pady=80)
# 检测到的人脸的标签
image_label_detected = tk.Label(win)
image_label_detected.pack(side=tk.LEFT, padx=10, pady=80)
# 滚动条和Canvas控件用于显示所有检测到的人脸
scrollbar = tk.Scrollbar(win)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
canvas = tk.Canvas(win, yscrollcommand=scrollbar.set)
canvas.pack(side=tk.BOTTOM, expand=True)
scrollbar.config(command=canvas.yview)
我们还要定义一个空的列表用来保存人脸部的图像
# 用于存储所有人脸图像的列表
face_images = []
创建图像中的按钮位置自己定义
# 创建选择图片和识别人脸的按钮
button_select = tk.Button(win, text="选择图片", font=my_font, command=select_image, fg='red')
button_select.place(x=333, y=12)
button_extract = tk.Button(win, text="提取人脸", font=my_font, command=extract_faces, fg='red')
button_extract.place(x=666, y=12)
esc = tk.Button(win, text='退出系统', font=30, command=Esc, fg='red')
esc.place(x=10, y=10)
t = tk.Button(win, text='返回系统', font=30, command=one, fg='red')
t.place(x=900, y=10)
创建函数
选择图片的函数和之前的一样这里直接写代码
def select_image():
global selected_image_path
selected_image_path = filedialog.askopenfilename()
# 显示原始图片
original_img = cv2.imread(selected_image_path)
original_img_rgb = cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB)
original_img_resized = cv2.resize(original_img_rgb, (600, 400)) # 将原始图片缩放到400x400大小
original_img_tk = ImageTk.PhotoImage(Image.fromarray(original_img_resized))
image_label_original.config(image=original_img_tk)
image_label_original.image = original_img_tk
提取人脸函数和人脸识别的区别是,我们在检测到人脸后需要把人脸区域裁剪下来显示到标签上,我们用列表来保存裁剪下来的人脸图片
def extract_faces():
if selected_image_path:
# 使用OpenCV加载图片
img = cv2.imread(selected_image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 加载预训练模型Hra来检测人脸
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades +
'haarcascade_frontalface_default.xml')
faces = face_cascade.detectMultiScale(gray, 1.1,
4)
# 创建一个空列表来存储所有的人脸图像
face_imgs = []
# 如果检测到人脸,裁剪并添加到列表
for (x, y, w, h) in faces:
face_img = img[y:y+h, x:x+w]
face_img_resized = cv2.resize(face_img, (100, 100))
face_imgs.append(face_img_resized)
# 转换为PIL图像并添加到Face_images列表中
face_img = cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)
face_img = Image.fromarray(face_img)
face_img = ImageTk.PhotoImage(face_img)
face_images.append(face_img)
# 更新图像列表显示
canvas.delete("all")
for i, face_img in enumerate(face_images):
canvas.create_image(0, i*100, anchor=tk.NW, image=face_img)
# 调整滚动条和Canvas大小
canvas.config(scrollregion=canvas.bbox("all"))
canvas.config(height=len(face_images)*100)
# 更新滚动条位置
canvas.yview_moveto(0)
# 如果没有人脸,显示警告信息
if not face_images:
messagebox.showinfo("信息", "没有检测到人脸")
else:
messagebox.showwarning("警告", "请先选择一张图片")
加上窗口刷新人脸提取的代码就完成了