提取人脸
导入所需的库
import tkinter as tk
from tkinter import filedialog
import cv2
from PIL import Image, ImageTk
from tkinter import messagebox
import subprocess
创建窗口
win = tk.Tk()
win.title("人脸提取")
win.geometry("800x650")
显示原始图片
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)
创建全局变量
selected_image_path = None
定义字体对象
my_font = ("Times New Roman", 20)
定义一个函数select_image
def select_image():
global selected_image_path
# 打开文件选择对话框
selected_image_path = filedialog.askopenfilename()
# 使用OpenCV加载图片
img = cv2.imread(selected_image_path)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_pil = Image.fromarray(img_rgb)
img_pil = img_pil.resize((300, 300), Image.Resampling.LANCZOS) # 调整图片大小为300x300
img_tk = ImageTk.PhotoImage(image=img_pil)
# 显示原始图片
image_label_original.config(image=img_tk)
image_label_original.image = img_tk
定义了extract_faces函数
def extract_faces():
if selected_image_path:
# 使用OpenCV的人脸检测
img = cv2.imread(selected_image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
# 打印检测到的人脸数量
print(f"Detected faces: {len(faces)}")
# 如果检测到人脸,裁剪并显示
if len(faces) > 0:
(x, y, w, h) = faces[0] # 获取第一个检测到的人脸
print(f"Face coordinates: x={x}, y={y}, w={w}, h={h}")
face_img = img[y:y+h, x:x+w] # 裁剪人脸区域
# 转换为PIL图像并调整大小
face_img = cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)
face_img = Image.fromarray(face_img)
face_img = face_img.resize((300, 300), Image.Resampling.LANCZOS) # 调整人脸图片大小为300x300
face_img = ImageTk.PhotoImage(face_img)
image_label_detected.config(image=face_img)
image_label_detected.image = face_img
else:
messagebox.showinfo("信息", "没有检测到人脸")
else:
messagebox.showwarning("警告", "请先选择一张图片")
设置按钮
创建选择图片和识别人脸的按钮
button_select = tk.Button(win, text="选择图片", font=my_font, command=select_image, fg='black')
button_select.place(x=150, y=12)
button_extract = tk.Button(win, text="提取人脸", font=my_font, command=extract_faces, fg='black')
button_extract.place(x=450, y=12)
运行GUI主循环
win.mainloop()
: 进入窗口win的主事件循环,使窗口显示并等待用户操作,直到用户关闭窗口。
win.mainloop()
运行显示
全部代码:
import tkinter as tk
from tkinter import filedialog
import cv2
from PIL import Image, ImageTk
from tkinter import messagebox
import subprocess
win = tk.Tk()
win.title("人脸提取")
win.geometry("800x650")
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)
selected_image_path = None
my_font = ("Times New Roman", 20)
def select_image():
global selected_image_path
# 打开文件选择对话框
selected_image_path = filedialog.askopenfilename()
# 使用OpenCV加载图片
img = cv2.imread(selected_image_path)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_pil = Image.fromarray(img_rgb)
img_pil = img_pil.resize((300, 300), Image.Resampling.LANCZOS) # 调整图片大小为300x300
img_tk = ImageTk.PhotoImage(image=img_pil)
# 显示原始图片
image_label_original.config(image=img_tk)
image_label_original.image = img_tk
# 人脸检测函数
def extract_faces():
if selected_image_path:
# 使用OpenCV的人脸检测
img = cv2.imread(selected_image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
# 打印检测到的人脸数量
print(f"Detected faces: {len(faces)}")
# 如果检测到人脸,裁剪并显示
if len(faces) > 0:
(x, y, w, h) = faces[0] # 获取第一个检测到的人脸
print(f"Face coordinates: x={x}, y={y}, w={w}, h={h}")
face_img = img[y:y+h, x:x+w] # 裁剪人脸区域
# 转换为PIL图像并调整大小
face_img = cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)
face_img = Image.fromarray(face_img)
face_img = face_img.resize((300, 300), Image.Resampling.LANCZOS) # 调整人脸图片大小为300x300
face_img = ImageTk.PhotoImage(face_img)
image_label_detected.config(image=face_img)
image_label_detected.image = face_img
else:
messagebox.showinfo("信息", "没有检测到人脸")
else:
messagebox.showwarning("警告", "请先选择一张图片")
# 创建选择图片和识别人脸的按钮
button_select = tk.Button(win, text="选择图片", font=my_font, command=select_image, fg='black')
button_select.place(x=150, y=12)
button_extract = tk.Button(win, text="提取人脸", font=my_font, command=extract_faces, fg='black')
button_extract.place(x=450, y=12)
win.mainloop()