OpenCv之简单的人脸识别项目(属性判断页面)

人脸识别

准备

本篇将展示属性判断页面,并与登录页面连接起来。动态处理页面分为预测性别和预测年龄两个分页面。

十二、属性判断页面

1.导入所需的包

tkinter:

Tkinter是Python的标准GUI(图形用户界面)库。它提供了一个快速和简单的方式来创建GUI应用程序。tkinter模块是Tkinter库的主模块,包含了创建窗口、按钮、文本框等基本GUI组件的类和函数。

messagebox:

这个模块是tkinter的一个扩展,提供了一个对话框,允许您显示消息框、警告框、错误框等。它是tkinter的一部分,通常与tkinter一起使用来与用户进行交互。

subprocess:

这个模块允许您启动新的进程,连接到它们的输入/输出/错误管道,并获取它们的返回码。通常用于执行系统命令或运行外部程序。

ImageTk:

ImageTk是PIL库中用于与Tkinter一起使用的模块,它提供了在Tkinter中显示图像的功能。它通常与Tkinter的PhotoImage类一起使用,以在Tkinter应用程序中显示PIL的Image对象。

import tkinter as tk
from tkinter import messagebox
import subprocess
from PIL import ImageTk, Image

2.设置窗口

2.1定义窗口外观和大小

实例化窗口,设置窗口标题,尺寸。

#设置窗口
win=tk.Tk()
win.title('属性判断')
win.geometry('600x450')

2.2设置窗口背景

2.2.1设置背景图片

调用image对象的resize方法来调整图像的大小。将调整大小后的PIL Image对象转换为Tkinter兼容的PhotoImage对象。

#背景设计
image = Image.open("15.gif")
image = image.resize((600, 450))  # 调整背景图片大小
photo1 = ImageTk.PhotoImage(image)
2.2.2创建label控件

Label控件可以用来显示文本、图像或其他内容。在这里,它被用来显示前面创建的PhotoImage对象,即背景图片。

canvas = tk.Label(win, image=photo1)
canvas.pack()

3.定义预测性别脚本

定义一个名为Spcl的函数,在Python中运行另一个名为 “预测性别.py” 的脚本,并在成功执行后关闭当前的Tkinter窗口 win。如果在这个过程中出现任何异常,它会弹出一个错误消息框,显示具体的错误信息。

# 定义预测性别
def ycxb():
    script_path = "预测性别.py"
    try:
        #运行文件
        subprocess.Popen(["python", script_path])
        win.destroy()
    except Exception as e:
        # 如果有错误,弹出消息框
        messagebox.showerror("Error", f"无法打开脚本:{e}")

4.定义预测年龄脚本

定义一个名为ycnl的函数,在Python中运行另一个名为 “预测年龄.py” 的脚本,并在成功执行后关闭当前的Tkinter窗口 win。如果在这个过程中出现任何异常,它会弹出一个错误消息框,显示具体的错误信息。

# 定义预测年龄
def ycnl():
    script_path = "预测年龄.py"
    try:
        #运行文件
        subprocess.Popen(["python", script_path])
        win.destroy()
    except Exception as e:
        # 如果有错误,弹出消息框
        messagebox.showerror("Error", f"无法打开脚本:{e}")

5.定义关闭窗口的函数

当用户点击一个按钮或执行其他操作以触发 close 函数时,当前的 Tkinter 窗口将被关闭,并且一个新的 Python 进程将被启动来执行 登录页面.py 脚本。

def close():
    subprocess.Popen(["python","登录页面.py"])
    win.destroy()

用法:close函数可以用来在应用程序中创建一个简单的退出功能,或者在需要时启动新的应用程序或脚本。

6.按钮设计

6.1预测性别按钮

设计一个按钮,用于在Tkinter图形用户界面中触发人脸识别功能。当用户点击这个按钮时,会调用之前定义的 ycxb函数。

# 按钮设计
image = Image.open("F16.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
bt1 = tk.Button(win, image=photo2, width=198, height=31,command=ycxb)
bt1.place(x=190, y=130)

6.2预测年龄按钮

设计一个按钮,用于在Tkinter图形用户界面中触发人脸识别功能。当用户点击这个按钮时,会调用之前定义的 ycnl函数。

image = Image.open("F17.gif")  # 加载一张图片
photo3 = ImageTk.PhotoImage(image)
bt2 = tk.Button(win, image=photo3, width=198, height=31,command=ycnl)
bt2.place(x=190, y=230)

6.3返回按钮

定义一个名为 bt3的按钮,该按钮将显示一个前面导入的名为 “B.gif” 的 图像,并且当用户点击这个按钮时,会执行一个名为 sb 的函数。

image = Image.open("B.gif")  # 加载一张图片
photo4 = ImageTk.PhotoImage(image)
bt3 = tk.Button(win, image=photo4, width=198, height=32,command=close)
bt3.place(x=190, y=330)

用法:close函数通常这个函数用来关闭应用程序窗口。

7.定义关键函数

win.mainloop() 是 Tkinter GUI 应用程序中的一个关键函数,它启动了 Tkinter 的事件循环。
这个事件循环是 GUI 应用程序的核心,它负责处理用户输入(如鼠标点击、按键等),更新窗口内容,以及响应用户的操作。

win.mainloop()

注:当你调用 win.mainloop() 时,以下几件事情会发生:
1.窗口 win 会显示在屏幕上。
2.应用程序会开始监听和响应事件,如按钮点击、输入框文字变化等。
3.当用户进行操作(如点击按钮),Tkinter 会触发相应的事件处理函数(例如,你设置的 command 参数对应的函数)。
4.如果没有事件发生,应用程序会保持空闲状态,不会占用太多CPU资源。
5.当你关闭窗口或者调用 win.destroy() 时,win.mainloop() 会退出,事件循环结束,应用程序终止。

8.属性判断页面运行结果图

在这里插入图片描述

属性判断页面完整代码

import tkinter as tk
from tkinter import messagebox
import subprocess
from PIL import ImageTk, Image



#设置窗口
win=tk.Tk()
win.title('属性判断')
win.geometry('600x450')


# 背景设计
image = Image.open("15.gif")
image = image.resize((600, 450))  # 调整背景图片大小
photo1 = ImageTk.PhotoImage(image)
canvas = tk.Label(win, image=photo1)
canvas.pack()

#定义预测性别
def ycxb():
    script_path = "预测性别.py"
    try:
        #运行文件
        subprocess.Popen(["python", script_path])
        win.destroy()
    except Exception as e:
        # 如果有错误,弹出消息框
        messagebox.showerror("Error", f"无法打开脚本:{e}")

#定义预测年龄
def ycnl():
    script_path = "预测年龄.py"
    try:
        # 运行文件
        subprocess.Popen(["python", script_path])
        win.destroy()
    except Exception as e:
        # 如果有错误,弹出消息框
        messagebox.showerror("Error", f"无法打开脚本:{e}")

def close():
    subprocess.Popen(["python","登录页面.py"])
    win.destroy()

# 按钮
image = Image.open("F16.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
bt1 = tk.Button(win, image=photo2, width=198, height=32,command=ycxb)
bt1.place(x=190, y=130)

image = Image.open("F17.gif")  # 加载一张图片
photo3 = ImageTk.PhotoImage(image)
bt2 = tk.Button(win, image=photo3, width=198, height=32,command=ycnl)
bt2.place(x=190, y=230)

image = Image.open("B.gif")  # 加载一张图片
photo4 = ImageTk.PhotoImage(image)
bt3 = tk.Button(win, image=photo4, width=198, height=32,command=close)
bt3.place(x=190, y=330)


win.mainloop()

十三、预测性别页面

1.导入所需的包

cv2 (OpenCV):

OpenCV是一个开源的计算机视觉库,它提供了大量用于图像和视频处理的功能。cv2模块是OpenCV的Python接口,它允许您在Python中使用OpenCV的功能。OpenCV广泛用于图像识别、图像处理、物体检测、视频分析等任务。

numpy:

NumPy是一个强大的数学库,它提供了大量的数学、逻辑、集合操作和数组操作功能。它还提供了一些高级的数据结构和函数,用于处理数组和矩阵。

tkinter:

Tkinter是Python的标准GUI(图形用户界面)库。它提供了一个快速和简单的方式来创建GUI应用程序。tkinter模块是Tkinter库的主模块,包含了创建窗口、按钮、文本框等基本GUI组件的类和函数。

subprocess:

这个模块允许您启动新的进程,连接到它们的输入/输出/错误管道,并获取它们的返回码。通常用于执行系统命令或运行外部程序。

filedialog:

这个模块是tkinter的一个扩展,提供了一个文件对话框,允许用户选择文件或目录。它是tkinter的一部分,通常与tkinter一起使用来创建文件选择器。

Label:

Label 是 Tkinter 中的一个组件,用于在窗口中显示文本或图像。在这个上下文中,它可能被用来显示图像或相关的文本信息。

Button:

Button 是 Tkinter 中的一个组件,用于创建按钮。用户可以通过点击按钮来触发某些操作,如打开文件对话框或执行特定的功能。

face_recognition:

这个模块是一个Python库,用于对人脸进行识别和对图片中的人脸进行定位。它使用深度学习算法来识别人脸,并且可以处理实时视频或静态图片。

PIL (Python Imaging Library):

PIL是一个强大的图像处理库,它支持多种图像文件格式,并提供了一系列图像处理功能,如打开、修改、保存图像,以及图像处理操作(如缩放、裁剪、颜色转换等)。

import cv2
import numpy as np
import tkinter as tk
import subprocess
from tkinter import filedialog, Label, Button
import face_recognition
from PIL import Image, ImageTk

2.加载预训练的模型

2.1加载预训练的人脸检测模型

使用 OpenCV 的 CascadeClassifier 函数加载了一个预先训练的人脸检测模型。这个模型保存在文件 haarcascade_frontalface_default.xml 中,它包含了检测人脸所需的特征。

# 加载预训练的人脸检测模型
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

2.2加载预训练的性别和年龄识别模型

分别使用 OpenCV 的 dnn.readNetFromCaffe 函数加载了两个预先训练的模型,用于性别和年龄的识别。这些模型保存在 deploy_gender.prototxt 和 deploy_age.prototxt 文件中,以及对应的 gender_net.caffemodel 和 age_net.caffemodel 文件中。

# 加载预训练的性别和年龄识别模型
gender_net = cv2.dnn.readNetFromCaffe('deploy_gender.prototxt', 'gender_net.caffemodel')
age_net = cv2.dnn.readNetFromCaffe('deploy_age.prototxt', 'age_net.caffemodel')

3.定义性别和年龄的标签列表

这两个列表分别定义了性别和年龄的标签。gender_list 包含两个性别标签 ‘Male’ 和 ‘Female’。age_list 包含不同的年龄范围标签,这些标签用于描述识别到的年龄组。

# 定义性别和年龄的标签列表
gender_list = ['Male', 'Female']
age_list = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']

4.创建窗口

定义窗口名称、尺寸。

# 创建 tkinter 窗口
root = tk.Tk()
root.title("预测性别")
root.geometry("750x600")

5.定义选择图片的函数

elect_image 函数的作用是让用户通过文件对话框选择一个图片文件,然后调用 display_image 函数来显示这个图片。

# 定义选择图片的函数
def select_image():
    file_path = filedialog.askopenfilename()
    if file_path:
        img = cv2.imread(file_path)
        if img is not None:
            display_image(file_path)

6.定义显示图片的函数

6.1函数定义和全局变量声明

定义了一个名为 display_image 的函数,并在函数内部声明了全局变量 img。这意味着函数内部对这个变量的修改将会影响函数外部的同名变量。

# 定义显示图片的函数
def display_image(file_path):
    # 确保 img 变量已经定义
    global img

6.2读取图像并转换格式

将调整后的图片从 OpenCV 的 NumPy 数组格式转换为 PIL 的图像格式。OpenCV 默认使用 BGR 颜色空间,而 PIL 使用 RGB 颜色空间,所以需要进行颜色空间转换。

def display_image(file_path):
    # 确保 img 变量已经定义
    global img
    img = cv2.imread(file_path)
    if img is not None:
        # 调整图像大小到相等的大小
        img = cv2.resize(img, (300, 300))  # 假设您想要将图像调整到 227x227 的大小

        # 将 OpenCV 图像转换为 PIL 图像
        pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

        # 在这里调整图像到固定大小
        pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

        # 将 PIL 图像转换为 tkinter 支持的格式
        image_tk = ImageTk.PhotoImage(pil_image)

6.3创建和显示图像标签

在 root 窗口中创建了一个新的 Label 组件,用于显示图像。它将 image_tk 设置为标签的图像,并将其放置在主窗口的 (30, 100) 位置。

# 在 root 窗口中创建一个标签来显示图像
label = tk.Label(root, image=image_tk)
label.image = image_tk  # 保持引用,否则图像在重新绘制时会丢失
label.place(x=30, y=100)

7.创建预测性别的函数

7.1全局变量声明和条件判断

首先声明 img 为全局变量。然后,它开始一个条件判断,检查 img 是否为 None。如果图片无法加载,img 将为 None。

# 创建预测性别的函数
def predict_gender():
    # 确保 img 变量已经定义
    global img
    if img is not None:

7.2 转换图像为灰度并检测人脸

将原始图像转换为灰度图像,因为大多数神经网络模型在处理图像时期望输入为灰度图像。然后,它使用之前加载的人脸检测模型 face_cascade 在灰度图像中检测人脸。detectMultiScale 函数返回一个包含所有检测到的人脸的边界框的列表。

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 检测人脸
faces = face_cascade.detectMultiScale(gray, 1.1, 4)

7.3 遍历检测到的人脸

遍历检测到的人脸,并为每个人脸裁剪出图像区域,并将其转换为一个可以输入到神经网络中的blob。然后,它使用性别识别模型 gender_net 对输入的blob进行预测,并从 gender_preds 列表中提取性别预测。它还在原始图像上绘制一个黄色矩形框来标记检测到的人脸,并在矩形框上方显示性别预测。

# 遍历检测到的人脸
for (x, y, w, h) in faces:
    # 从原始图像中裁剪人脸区域
    face_img = img[y:y + h, x:x + w].copy()

    # 预处理人脸图像以适应神经网络输入
    blob = cv2.dnn.blobFromImage(face_img, 1, (227, 227), (78.4263377603, 87.7689143744, 114.895847746), swapRB=False)

    # 预测性别
    gender_net.setInput(blob)
    gender_preds = gender_net.forward()
    gender = gender_list[gender_preds[0].argmax()]

    # 在人脸周围画框并显示性别
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2)
    cv2.putText(img, f'{gender}', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2, cv2.LINE_AA)

7.4 转换图像格式和显示

将调整后的图像从 OpenCV 的 NumPy 数组格式转换为 PIL 的图像格式,并将其调整到 300x400 像素的大小。然后,它将调整后的 PIL 图像转换为 Tkinter 可以显示的 PhotoImage 对象,并在 root 窗口中创建一个标签来显示图像。

# 将 OpenCV 图像转换为 PIL 图像
pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

# 在这里调整图像到固定大小
pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

# 将 PIL 图像转换为 tkinter 支持的格式
image_tk = ImageTk.PhotoImage(pil_image)


# 在 root 窗口中创建一个标签来显示图像
label = tk.Label(root, image=image_tk)
label.image = image_tk  # 保持引用,否则图像在重新绘制时会丢失
label.place(x=360, y=100)



# 将 OpenCV 图像转换为 PIL 图像
pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

# 在这里调整图像到固定大小
pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

# 将 PIL 图像转换为 tkinter 支持的格式
image_tk = ImageTk.PhotoImage(pil_image)

总结:predict_gender 函数的作用是在用户选择的图片中检测人脸,并预测这些人脸的性别。它将预测结果显示在原始图像上,并更新 Tkinter 窗口以显示更新后的图像。

8.定义关闭窗口的函数

当用户点击一个按钮或执行其他操作以触发 close 函数时,当前的 Tkinter 窗口将被关闭,并且一个新的 Python 进程将被启动来执行 登录页面.py 脚本。

def close():
    subprocess.Popen(["python","属性判断.py"])
    root.destroy()

用法:close函数可以用来在应用程序中创建一个简单的退出功能,或者在需要时启动新的应用程序或脚本。

9.按钮设计

9.1选择图片按钮

设计一个按钮,用于在Tkinter图形用户界面中触发选择图片功能。当用户点击这个按钮时,会调用之前定义的select_image函数。

# 创建一个按钮,用于打开文件选择对话框
image = Image.open("A.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
open_image_btn=tk.Button(root, image=photo2, width=198, height=31,command=select_image)
open_image_btn.place(x=30,y=30)

9.2预测性别按钮

设计一个按钮,用于在Tkinter图形用户界面中触发预测性别功能。当用户点击这个按钮时,会调用之前定义的predict_gender函数。

# 按钮设计
image = Image.open("F16.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
bt1 = tk.Button(win, image=photo2, width=198, height=31,command=predict_gender)
bt1.place(x=190, y=130)

9.3返回按钮

定义一个名为 bt3的按钮,该按钮将显示一个前面导入的名为 “B.gif” 的 图像,并且当用户点击这个按钮时,会执行一个名为 sb的函数。

image = Image.open("B.gif")  # 加载一张图片
photo4 = ImageTk.PhotoImage(image)
bt3 = tk.Button(win, image=photo4, width=198, height=32,command=close)
bt3.place(x=520, y=30)

用法:close函数通常这个函数用来关闭应用程序窗口。

10.定义关键函数

root.mainloop() 是 Tkinter GUI 应用程序中的一个关键函数,它启动了 Tkinter 的事件循环。
这个事件循环是 GUI 应用程序的核心,它负责处理用户输入(如鼠标点击、按键等),更新窗口内容,以及响应用户的操作。

root.mainloop()

注:当你调用 win.mainloop() 时,以下几件事情会发生:
1.窗口 root 会显示在屏幕上。
2.应用程序会开始监听和响应事件,如按钮点击、输入框文字变化等。
3.当用户进行操作(如点击按钮),Tkinter 会触发相应的事件处理函数(例如,你设置的 command 参数对应的函数)。
4.如果没有事件发生,应用程序会保持空闲状态,不会占用太多CPU资源。
5.当你关闭窗口或者调用 root.destroy() 时,root.mainloop() 会退出,事件循环结束,应用程序终止。

11. 预测性别页面运行结果图

在这里插入图片描述

11.预测性别页面功能展示图

在这里插入图片描述

预测性别页面完整代码

import cv2
import numpy as np
import tkinter as tk
import subprocess
from tkinter import filedialog, Label, Button
import face_recognition
from PIL import Image, ImageTk

# 加载预训练的人脸检测模型
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# 加载预训练的性别和年龄识别模型
gender_net = cv2.dnn.readNetFromCaffe('deploy_gender.prototxt', 'gender_net.caffemodel')
age_net = cv2.dnn.readNetFromCaffe('deploy_age.prototxt', 'age_net.caffemodel')

# 定义性别和年龄的标签列表
gender_list = ['Male', 'Female']
age_list = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']

# 创建 tkinter 窗口
root = tk.Tk()
root.title("预测性别")
root.geometry("750x600")

# 定义选择图片的函数
def select_image():
    file_path = filedialog.askopenfilename()
    if file_path:
        img = cv2.imread(file_path)
        if img is not None:
            display_image(file_path)

# 创建一个按钮,用于打开文件选择对话框
image = Image.open("A.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
open_image_btn = tk.Button(root, image=photo2, width=198, height=31,command=select_image)
open_image_btn.place(x=30,y=30)

# 定义显示图片的函数
def display_image(file_path):
    # 确保 img 变量已经定义
    global img
    img = cv2.imread(file_path)
    if img is not None:
        # 调整图像大小到相等的大小
        img = cv2.resize(img, (300, 300))  # 假设您想要将图像调整到 227x227 的大小

        # 将 OpenCV 图像转换为 PIL 图像
        pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

        # 在这里调整图像到固定大小
        pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

        # 将 PIL 图像转换为 tkinter 支持的格式
        image_tk = ImageTk.PhotoImage(pil_image)

        # 在 root 窗口中创建一个标签来显示图像
        label = tk.Label(root, image=image_tk)
        label.image = image_tk  # 保持引用,否则图像在重新绘制时会丢失
        label.place(x=30, y=100)
        # label.pack()

# 创建预测性别的函数
def predict_gender():
    # 确保 img 变量已经定义
    global img
    if img is not None:
        # 转换为灰度图像
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        # 检测人脸
        faces = face_cascade.detectMultiScale(gray, 1.1, 4)

        # 遍历检测到的人脸
        for (x, y, w, h) in faces:
            # 从原始图像中裁剪人脸区域
            face_img = img[y:y + h, x:x + w].copy()

            # 预处理人脸图像以适应神经网络输入
            blob = cv2.dnn.blobFromImage(face_img, 1, (227, 227), (78.4263377603, 87.7689143744, 114.895847746), swapRB=False)

            # 预测性别
            gender_net.setInput(blob)
            gender_preds = gender_net.forward()
            gender = gender_list[gender_preds[0].argmax()]

            # 在人脸周围画框并显示性别
            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2)
            cv2.putText(img, f'{gender}', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2, cv2.LINE_AA)


            # 将 OpenCV 图像转换为 PIL 图像
            pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

            # 在这里调整图像到固定大小
            pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

            # 将 PIL 图像转换为 tkinter 支持的格式
            image_tk = ImageTk.PhotoImage(pil_image)


            # 在 root 窗口中创建一个标签来显示图像
            label = tk.Label(root, image=image_tk)
            label.image = image_tk  # 保持引用,否则图像在重新绘制时会丢失
            label.place(x=360, y=100)


            # 将 OpenCV 图像转换为 PIL 图像
            pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

            # 在这里调整图像到固定大小
            pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

            # 将 PIL 图像转换为 tkinter 支持的格式
            image_tk = ImageTk.PhotoImage(pil_image)



def close():
    subprocess.Popen(["python","属性判断.py"])
    root.destroy()

# 创建预测性别的按钮
image = Image.open("F16.gif")  # 加载一张图片
photo3 = ImageTk.PhotoImage(image)
predict_gender_btn = tk.Button(root, image=photo3, command=predict_gender)
predict_gender_btn.place(x=275,y=30)

image = Image.open("B.gif")  # 加载一张图片
photo4 = ImageTk.PhotoImage(image)
bt3 = tk.Button(image=photo4, width=198, height=32,command=close)
bt3.place(x=520, y=30)

# 运行 tkinter 事件循环
root.mainloop()

十四、预测年龄页面

1.导入所需的包

cv2 (OpenCV):

OpenCV是一个开源的计算机视觉库,它提供了大量用于图像和视频处理的功能。cv2模块是OpenCV的Python接口,它允许您在Python中使用OpenCV的功能。OpenCV广泛用于图像识别、图像处理、物体检测、视频分析等任务。

numpy:

NumPy是一个强大的数学库,它提供了大量的数学、逻辑、集合操作和数组操作功能。它还提供了一些高级的数据结构和函数,用于处理数组和矩阵。

tkinter:

Tkinter是Python的标准GUI(图形用户界面)库。它提供了一个快速和简单的方式来创建GUI应用程序。tkinter模块是Tkinter库的主模块,包含了创建窗口、按钮、文本框等基本GUI组件的类和函数。

subprocess:

这个模块允许您启动新的进程,连接到它们的输入/输出/错误管道,并获取它们的返回码。通常用于执行系统命令或运行外部程序。

filedialog:

这个模块是tkinter的一个扩展,提供了一个文件对话框,允许用户选择文件或目录。它是tkinter的一部分,通常与tkinter一起使用来创建文件选择器。

Label:

Label 是 Tkinter 中的一个组件,用于在窗口中显示文本或图像。在这个上下文中,它可能被用来显示图像或相关的文本信息。

Button:

Button 是 Tkinter 中的一个组件,用于创建按钮。用户可以通过点击按钮来触发某些操作,如打开文件对话框或执行特定的功能。

face_recognition:

这个模块是一个Python库,用于对人脸进行识别和对图片中的人脸进行定位。它使用深度学习算法来识别人脸,并且可以处理实时视频或静态图片。

PIL (Python Imaging Library):

PIL是一个强大的图像处理库,它支持多种图像文件格式,并提供了一系列图像处理功能,如打开、修改、保存图像,以及图像处理操作(如缩放、裁剪、颜色转换等)。

import cv2
import numpy as np
import tkinter as tk
import subprocess
from tkinter import filedialog, Label, Button
import face_recognition
from PIL import Image, ImageTk

2.加载预训练的模型

2.1加载预训练的人脸检测模型

使用 OpenCV 的 CascadeClassifier 函数加载了一个预先训练的人脸检测模型。这个模型保存在文件 haarcascade_frontalface_default.xml 中,它包含了检测人脸所需的特征。

# 加载预训练的人脸检测模型
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

2.2加载预训练的性别和年龄识别模型

分别使用 OpenCV 的 dnn.readNetFromCaffe 函数加载了两个预先训练的模型,用于性别和年龄的识别。这些模型保存在 deploy_gender.prototxt 和 deploy_age.prototxt 文件中,以及对应的 gender_net.caffemodel 和 age_net.caffemodel 文件中。

# 加载预训练的性别和年龄识别模型
gender_net = cv2.dnn.readNetFromCaffe('deploy_gender.prototxt', 'gender_net.caffemodel')
age_net = cv2.dnn.readNetFromCaffe('deploy_age.prototxt', 'age_net.caffemodel')

3.定义性别和年龄的标签列表

这两个列表分别定义了性别和年龄的标签。gender_list 包含两个性别标签 ‘Male’ 和 ‘Female’。age_list 包含不同的年龄范围标签,这些标签用于描述识别到的年龄组。

# 定义性别和年龄的标签列表
gender_list = ['Male', 'Female']
age_list = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']

4.创建窗口

定义窗口名称、尺寸。

# 创建 tkinter 窗口
root = tk.Tk()
root.title("预测性别")
root.geometry("750x600")

5.定义选择图片的函数

elect_image 函数的作用是让用户通过文件对话框选择一个图片文件,然后调用 display_image 函数来显示这个图片。

# 定义选择图片的函数
def select_image():
    file_path = filedialog.askopenfilename()
    if file_path:
        img = cv2.imread(file_path)
        if img is not None:
            display_image(file_path)

6.定义显示图片的函数

6.1函数定义和全局变量声明

定义了一个名为 display_image 的函数,并在函数内部声明了全局变量 img。这意味着函数内部对这个变量的修改将会影响函数外部的同名变量。

# 定义显示图片的函数
def display_image(file_path):
    # 确保 img 变量已经定义
    global img

6.2读取图像并转换格式

将调整后的图片从 OpenCV 的 NumPy 数组格式转换为 PIL 的图像格式。OpenCV 默认使用 BGR 颜色空间,而 PIL 使用 RGB 颜色空间,所以需要进行颜色空间转换。

def display_image(file_path):
    # 确保 img 变量已经定义
    global img
    img = cv2.imread(file_path)
    if img is not None:
        # 调整图像大小到相等的大小
        img = cv2.resize(img, (300, 300))  # 假设您想要将图像调整到 227x227 的大小

        # 将 OpenCV 图像转换为 PIL 图像
        pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

        # 在这里调整图像到固定大小
        pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

        # 将 PIL 图像转换为 tkinter 支持的格式
        image_tk = ImageTk.PhotoImage(pil_image)

6.3创建和显示图像标签

在 root 窗口中创建了一个新的 Label 组件,用于显示图像。它将 image_tk 设置为标签的图像,并将其放置在主窗口的 (30, 100) 位置。

# 在 root 窗口中创建一个标签来显示图像
label = tk.Label(root, image=image_tk)
label.image = image_tk  # 保持引用,否则图像在重新绘制时会丢失
label.place(x=30, y=100)

7.创建预测年龄的函数

7.1全局变量声明和条件判断

首先声明 img 为全局变量。然后,它开始一个条件判断,检查 img 是否为 None。如果图片无法加载,img 将为 None。

# 创建预测年龄的函数
def predict_age():
    # 确保 img 变量已经定义
    global img
    if img is not None:

7.2 转换图像为灰度并检测人脸

将原始图像转换为灰度图像,因为大多数神经网络模型在处理图像时期望输入为灰度图像。然后,它使用之前加载的人脸检测模型 face_cascade 在灰度图像中检测人脸。detectMultiScale 函数返回一个包含所有检测到的人脸的边界框的列表。

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 检测人脸
faces = face_cascade.detectMultiScale(gray, 1.1, 4)

7.3 遍历检测到的人脸

遍历检测到的人脸,并为每个人脸裁剪出图像区域,并将其转换为一个可以输入到神经网络中的blob。然后,它使用性别识别模型 gender_net 对输入的blob进行预测,并从 gender_preds 列表中提取性别预测。它还在原始图像上绘制一个黄色矩形框来标记检测到的人脸,并在矩形框上方显示性别预测。

# 遍历检测到的人脸
for (x, y, w, h) in faces:
    # 从原始图像中裁剪人脸区域
    face_img = img[y:y + h, x:x + w].copy()

    # 预处理人脸图像以适应神经网络输入
    blob = cv2.dnn.blobFromImage(face_img, 1, (227, 227), (78.4263377603, 87.7689143744, 114.895847746), swapRB=False)

    # 预测年龄
    age_net.setInput(blob)
    age_preds = age_net.forward()
    age = age_list[age_preds[0].argmax()]

    # 在人脸周围画框并显示年龄
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2)
    cv2.putText(img, f'{age}', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2, cv2.LINE_AA)

7.4 转换图像格式和显示

将调整后的图像从 OpenCV 的 NumPy 数组格式转换为 PIL 的图像格式,并将其调整到 300x400 像素的大小。然后,它将调整后的 PIL 图像转换为 Tkinter 可以显示的 PhotoImage 对象,并在 root 窗口中创建一个标签来显示图像。

 # 将 OpenCV 图像转换为 PIL 图像
 pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

 # 在这里调整图像到固定大小
 pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

 # 将 PIL 图像转换为 tkinter 支持的格式
 image_tk = ImageTk.PhotoImage(pil_image)


 # 在 root 窗口中创建一个标签来显示图像
 label = tk.Label(root, image=image_tk)
 label.image = image_tk  # 保持引用,否则图像在重新绘制时会丢失
 label.place(x=360, y=100)



# 将 OpenCV 图像转换为 PIL 图像
 pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

 # 在这里调整图像到固定大小
 pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

 # 将 PIL 图像转换为 tkinter 支持的格式
 image_tk = ImageTk.PhotoImage(pil_image)

总结:predict_age 函数的作用是在用户选择的图片中检测人脸,并预测这些人脸的年龄。它将预测结果显示在原始图像上,并更新 Tkinter 窗口以显示更新后的图像。

8.定义关闭窗口的函数

当用户点击一个按钮或执行其他操作以触发 close 函数时,当前的 Tkinter 窗口将被关闭,并且一个新的 Python 进程将被启动来执行 登录页面.py 脚本。

def close():
    subprocess.Popen(["python","属性判断.py"])
    root.destroy()

用法:close函数可以用来在应用程序中创建一个简单的退出功能,或者在需要时启动新的应用程序或脚本。

9.按钮设计

9.1选择图片按钮

设计一个按钮,用于在Tkinter图形用户界面中触发选择图片功能。当用户点击这个按钮时,会调用之前定义的select_image函数。

# 创建一个按钮,用于打开文件选择对话框
image = Image.open("A.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
open_image_btn=tk.Button(root, image=photo2, width=198, height=31,command=select_image)
open_image_btn.place(x=30,y=30)

9.2预测年龄按钮

设计一个按钮,用于在Tkinter图形用户界面中触发预测性别功能。当用户点击这个按钮时,会调用之前定义的predict_gender函数。

# 按钮设计
image = Image.open("F17.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
bt1 = tk.Button(win, image=photo2, width=198, height=31,command=predict_gender)
bt1.place(x=190, y=130)

9.3返回按钮

定义一个名为 bt3的按钮,该按钮将显示一个前面导入的名为 “B.gif” 的 图像,并且当用户点击这个按钮时,会执行一个名为 sb的函数。

image = Image.open("B.gif")  # 加载一张图片
photo4 = ImageTk.PhotoImage(image)
bt3 = tk.Button(win, image=photo4, width=198, height=32,command=close)
bt3.place(x=520, y=30)

用法:close函数通常这个函数用来关闭应用程序窗口。

10.定义关键函数

root.mainloop() 是 Tkinter GUI 应用程序中的一个关键函数,它启动了 Tkinter 的事件循环。
这个事件循环是 GUI 应用程序的核心,它负责处理用户输入(如鼠标点击、按键等),更新窗口内容,以及响应用户的操作。

root.mainloop()

注:当你调用 win.mainloop() 时,以下几件事情会发生:
1.窗口 root 会显示在屏幕上。
2.应用程序会开始监听和响应事件,如按钮点击、输入框文字变化等。
3.当用户进行操作(如点击按钮),Tkinter 会触发相应的事件处理函数(例如,你设置的 command 参数对应的函数)。
4.如果没有事件发生,应用程序会保持空闲状态,不会占用太多CPU资源。
5.当你关闭窗口或者调用 root.destroy() 时,root.mainloop() 会退出,事件循环结束,应用程序终止。

11. 预测年龄页面运行结果图

在这里插入图片描述

11.预测年龄页面功能展示图

在这里插入图片描述

预测年龄页面完整代码

import cv2
import numpy as np
import tkinter as tk
import subprocess
from tkinter import filedialog, Label, Button
import face_recognition
from PIL import Image, ImageTk

# 加载预训练的人脸检测模型
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# 加载预训练的性别和年龄识别模型
gender_net = cv2.dnn.readNetFromCaffe('deploy_gender.prototxt', 'gender_net.caffemodel')
age_net = cv2.dnn.readNetFromCaffe('deploy_age.prototxt', 'age_net.caffemodel')

# 定义性别和年龄的标签列表
gender_list = ['Male', 'Female']
age_list = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']

# 创建 tkinter 窗口
root = tk.Tk()
root.title("选择图片")
root.geometry("750x600")

#设置背景图
image = Image.open("17.gif")
image = image.resize((750, 600))  # 调整背景图片大小
photo1 = ImageTk.PhotoImage(image)
# 创建Label并将背景图片设置为背景
canvas = tk.Label(root, image=photo1)
canvas.pack()

# 定义选择图片的函数
def select_image():
    file_path = filedialog.askopenfilename()
    if file_path:
        img = cv2.imread(file_path)
        if img is not None:
            display_image(file_path)

# 创建一个按钮,用于打开文件选择对话框
image = Image.open("A.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
open_image_btn = tk.Button(root, image=photo2, command=select_image)
open_image_btn.place(x=30,y=30)

# 定义显示图片的函数
def display_image(file_path):
    # 确保 img 变量已经定义
    global img
    img = cv2.imread(file_path)
    if img is not None:
        # 调整图像大小到相等的大小
        img = cv2.resize(img, (300, 300))  # 假设您想要将图像调整到 227x227 的大小

        # 将 OpenCV 图像转换为 PIL 图像
        pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

        # 在这里调整图像到固定大小
        pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

        # 将 PIL 图像转换为 tkinter 支持的格式
        image_tk = ImageTk.PhotoImage(pil_image)

        # 在 root 窗口中创建一个标签来显示图像
        label = tk.Label(root, image=image_tk)
        label.image = image_tk  # 保持引用,否则图像在重新绘制时会丢失
        label.place(x=30, y=100)
        # label.pack()

# 创建预测年龄的函数
def predict_age():
    # 确保 img 变量已经定义
    global img
    if img is not None:
        # 转换为灰度图像
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        # 检测人脸
        faces = face_cascade.detectMultiScale(gray, 1.1, 4)

        # 遍历检测到的人脸
        for (x, y, w, h) in faces:
            # 从原始图像中裁剪人脸区域
            face_img = img[y:y + h, x:x + w].copy()

            # 预处理人脸图像以适应神经网络输入
            blob = cv2.dnn.blobFromImage(face_img, 1, (227, 227), (78.4263377603, 87.7689143744, 114.895847746), swapRB=False)

            # 预测年龄
            age_net.setInput(blob)
            age_preds = age_net.forward()
            age = age_list[age_preds[0].argmax()]

            # 在人脸周围画框并显示年龄
            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2)
            cv2.putText(img, f'{age}', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2, cv2.LINE_AA)


            # 将 OpenCV 图像转换为 PIL 图像
            pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

            # 在这里调整图像到固定大小
            pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

            # 将 PIL 图像转换为 tkinter 支持的格式
            image_tk = ImageTk.PhotoImage(pil_image)


            # 在 root 窗口中创建一个标签来显示图像
            label = tk.Label(root, image=image_tk)
            label.image = image_tk  # 保持引用,否则图像在重新绘制时会丢失
            label.place(x=360, y=100)


           # 将 OpenCV 图像转换为 PIL 图像
            pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

            # 在这里调整图像到固定大小
            pil_image = pil_image.resize((300, 400))  # 调整图像到300x400像素

            # 将 PIL 图像转换为 tkinter 支持的格式
            image_tk = ImageTk.PhotoImage(pil_image)


def close():
    subprocess.Popen(["python","属性判断.py"])
    root.destroy()

# 创建预测年龄的按钮
image = Image.open("F17.gif")  # 加载一张图片
photo3 = ImageTk.PhotoImage(image)
predict_age_btn = tk.Button(root, image=photo3, command=predict_age)
predict_age_btn.place(x=275,y=30)

image = Image.open("B.gif")  # 加载一张图片
photo4 = ImageTk.PhotoImage(image)
bt3 = tk.Button(image=photo4, width=198, height=32,command=close)
bt3.place(x=520, y=30)

# 运行 tkinter 事件循环
root.mainloop()

  • 31
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值