首页 > 其他分享 >UI界面设计-Fer2013面部表情识别/基于pytorch

UI界面设计-Fer2013面部表情识别/基于pytorch

时间:2024-08-04 08:59:58浏览次数:17  
标签:界面设计 scale self torch pytorch UI tk 模型 加载

基于tensorflow代码请参考主页:

http://t.csdnimg.cn/beYP5icon-default.png?t=N7T8http://t.csdnimg.cn/beYP5本文使用torch框架构建模型做出UI界面,将所有调参变量做到UI界面上

一、项目概述

本项目开发了一款集成深度学习的情绪识别软件,采用 PyTorch 框架构建卷积神经网络模型。该软件通过摄像头捕获实时视频流,利用 Haar 级联分类器检测人脸,并应用训练好的模型分析表情,最终识别出七种基本情绪:愤怒、厌恶、恐惧、快乐、中立、悲伤和惊讶。此外,我们特别设计了一个直观的图形用户界面(GUI),使用 Tkinter 库实现,使用户能够轻松调整关键参数,优化识别效果。

(1)核心功能

  • 动态参数调整:用户可通过 GUI 上的滑块调整两个重要参数——缩放因子和最小邻居数。缩放因子控制图像金字塔中的图像尺寸缩放比例,影响检测到人脸的大小范围;而最小邻居数则确保只有经过多次验证的候选区域才被视为真实的人脸,平衡了检测精度和速度。

  • 实时情绪反馈:软件在视频流中实时高亮显示检测到的人脸区域,并在界面上方即时呈现识别到的情绪类别,便于观察者理解情绪状态。

  • 模型加载与保存:用户可以加载预先训练的模型权重文件(.pth格式),确保软件能够立即投入使用,无需重新训练模型。

(2)用户界面设计

  • 简洁直观的操作面板:包含“加载模型”和“开始检测”按钮,以及参数调整滑块,方便用户快速配置。

  • 实时视频预览区:主界面中央显示摄像头捕获的视频流,实时更新检测结果。

  • 状态提示:通过弹窗通知用户模型加载情况和其他重要信息。

(3)应用场景与参数调整建议

在不同的光照条件或拍摄角度下,适当调整缩放因子和最小邻居数可显著提升识别准确率。例如,在低光照环境下,增加最小邻居数有助于减少误报,但在部分遮挡的情况下,降低这一数值则可能避免漏检。

一、代码如下所示:

import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from PIL import Image, ImageTk
import numpy as np
import cv2
import torch
import torch.nn as nn
import torch.nn.functional as F
import os

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
        self.conv4 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1)
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.dropout1 = nn.Dropout(0.25)
        self.dropout2 = nn.Dropout(0.5)
        self.fc1 = nn.Linear(128 * 6 * 6, 1024)
        self.fc2 = nn.Linear(1024, 7)
    
    def forward(self, x):
        x = torch.relu(self.conv1(x))
        x = self.pool(torch.relu(self.conv2(x)))
        x = self.dropout1(x)
        x = self.pool(torch.relu(self.conv3(x)))
        x = self.pool(torch.relu(self.conv4(x)))
        x = self.dropout1(x)
        x = x.view(-1, 128*6*6)  # Flatten the tensor
        x = self.fc1(x)
        x = torch.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        return x

class EmotionRecognitionApp:
    def __init__(self, master):
        self.master = master
        master.title("情绪识别")

        self.model = CNN()
        self.weights_path = ''
        self.load_model()

        #self.emotion_dict = {0: "生气", 1: "厌恶", 2: "恐惧", 3: "高兴", 4: "中性", 5: "悲伤", 6: "惊讶"}
        self.emotion_dict = {0: "Angry", 1: "Disgusted", 2: "Fearful", 3: "Happy", 4: "Neutral", 5: "Sad", 6: "Surprised"}
        self.cap = cv2.VideoCapture(0)
        self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

        self.canvas = tk.Canvas(master, width=890, height=650)
        self.canvas.pack()

        self.create_widgets()

    def create_widgets(self):
        # 加载模型按钮
        self.load_button = tk.Button(self.master, text="加载模型", command=self.load_model_dialog)
        self.load_button.pack(side=tk.LEFT)

        # 开始检测按钮
        self.detect_button = tk.Button(self.master, text="开始检测", command=self.start_detection)
        self.detect_button.pack(side=tk.LEFT)

        # 缩放因子滑块
        self.scale_factor_label = tk.Label(self.master, text="缩放因子:")
        self.scale_factor_label.pack(side=tk.LEFT)
        self.scale_factor_scale = tk.Scale(self.master, from_=1.0, to=2.0, resolution=0.1, orient=tk.HORIZONTAL, label="缩放因子")
        self.scale_factor_scale.set(1.3)
        self.scale_factor_scale.bind('<ButtonRelease-1>', self.update_scale_factor)
        self.scale_factor_scale.pack(side=tk.LEFT)

        # 最小邻居数滑块
        self.min_neighbors_label = tk.Label(self.master, text="最小邻居数:")
        self.min_neighbors_label.pack(side=tk.LEFT)
        self.min_neighbors_scale = tk.Scale(self.master, from_=2, to=10, resolution=1, orient=tk.HORIZONTAL, label="最小邻居数")
        self.min_neighbors_scale.set(5)
        self.min_neighbors_scale.bind('<ButtonRelease-1>', self.update_min_neighbors)
        self.min_neighbors_scale.pack(side=tk.LEFT)

    def load_model_dialog(self):
        self.weights_path = filedialog.askopenfilename(title="选择模型权重", filetypes=[("PyTorch Model", "*.pth")])
        if self.weights_path:
            self.model.load_state_dict(torch.load(self.weights_path, map_location=torch.device('cpu')))
            messagebox.showinfo("信息", "模型加载成功!")

    def load_model(self):
        # 默认模型加载(更新为你的默认模型路径)
        default_path = 'model_1000.pth'
        if os.path.exists(default_path):
            self.weights_path = default_path
            self.model.load_state_dict(torch.load(default_path, map_location=torch.device('cpu')))
            messagebox.showinfo("信息", "默认模型加载成功!")

    def update_frame(self):
        ret, frame = self.cap.read()
        if not ret:
            messagebox.showerror("错误", "无法从摄像头读取帧。")
            return

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = self.face_cascade.detectMultiScale(gray, scaleFactor=self.scale_factor, minNeighbors=self.min_neighbors)

        for (x, y, w, h) in faces:
            cv2.rectangle(frame, (x, y-50), (x+w, y+h+10), (255, 0, 0), 2)
            roi_gray = gray[y:y + h, x:x + w]
            cropped_img = cv2.resize(roi_gray, (48, 48))
            cropped_img = np.expand_dims(cropped_img, axis=0)
            cropped_img = np.expand_dims(cropped_img, axis=0)
            cropped_img = torch.from_numpy(cropped_img).float()
            prediction = self.model(cropped_img)
            prediction = F.softmax(prediction, dim=1)
            maxindex = int(torch.argmax(prediction).item())
            cv2.putText(frame, self.emotion_dict[maxindex], (x+20, y-60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)

        img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        self.photo = ImageTk.PhotoImage(image=Image.fromarray(img))
        self.canvas.create_image(0, 0, image=self.photo, anchor=tk.NW)
        self.master.after(10, self.update_frame)

    def start_detection(self):
        if not self.weights_path:
            messagebox.showerror("错误", "请先加载一个模型。")
            return
        self.scale_factor = self.scale_factor_scale.get()
        self.min_neighbors = int(self.min_neighbors_scale.get())
        self.update_frame()

    def update_scale_factor(self, event):
        self.scale_factor = self.scale_factor_scale.get()

    def update_min_neighbors(self, event):
        self.min_neighbors = int(self.min_neighbors_scale.get())

    def on_closing(self):
        self.cap.release()
        self.master.quit()

def main():
    root = tk.Tk()
    app = EmotionRecognitionApp(root)

    root.protocol("WM_DELETE_WINDOW", app.on_closing)
    root.mainloop()

if __name__ == "__main__":
    main()

二、代码流程图

三、UI效果图

UI效果图描述:

在UI界面上,用户首先会看到一个简洁明了的窗口,其中包括了两个主要的操作按钮:“加载模型”和“开始检测”。通过点击“加载模型”按钮,用户可以浏览并选择一个预先训练好的模型权重文件(.pth格式)。成功加载模型后,会弹出提示信息确认模型已加载。

在界面的下方,用户可以通过两个滑块来调整“缩放因子”和“最小邻居数”。这些参数对于优化人脸检测的准确性至关重要。调整完毕后,用户可以点击“开始检测”按钮,此时程序将开始从摄像头捕获视频流,并实时显示情绪识别的结果。

情绪识别的结果会以文本的形式显示在检测到的人脸下方,使用不同的颜色和字体样式以提高可读性。用户可以随时通过关闭窗口或点击退出按钮来结束程序。

首先实现基于pytorch的情绪识别,如下所示

实现将所有调参变量做到UI界面上,将使用 tkinter 库来创建一个图形用户界面,允许用户通过滑块调整参数,并显示实时视频流和情绪识别结果

运行代码,点击加载模型,将之前跑好的pth文件导入,显示模型加载成功后,点击开始检测。

即可进行情绪识别,如下所示

(1)缩放因子

        这个参数决定了在图像金字塔中,每一层图像的缩放比例。具体来说,它是在每次向下采样时,图像尺寸缩小的比例。较高的缩放因子可以使检测器检测到更小的人脸,但同时也会增加误检(false positives)的可能性,因为较小的特征变化可能会被错误地识别为人脸。

(2)与最小邻居数

        决定在检测过程中,一个候选区域需要有多少个邻近的候选区域才能被确认为真正的人脸。较高的最小邻居数可以减少误检,因为它要求候选区域在多个尺度上都被检测到,从而增加了检测的可靠性。但同时,它也可能错过一些真正的人脸,特别是当人脸在图像中不明显或部分被遮挡时。

(3)考虑场景

        在不同的应用场景中,可能需要根据实际情况调整这些参数。例如,在光照条件较差的环境中,可能需要增加最小邻居数以减少误检。

通过在 UI 界面上提供这些参数的调整选项,用户可以根据自己的需求和环境来优化情绪检测的效果。

感谢你的阅读,祝你生活愉快~

标签:界面设计,scale,self,torch,pytorch,UI,tk,模型,加载
From: https://blog.csdn.net/wangzhengyang214/article/details/140898966

相关文章

  • 【PyTorch】多对象分割项目
     【PyTorch】单对象分割项目对象分割任务的目标是找到图像中目标对象的边界。实际应用例如自动驾驶汽车和医学成像分析。这里将使用PyTorch开发一个深度学习模型来完成多对象分割任务。多对象分割的主要目标是自动勾勒出图像中多个目标对象的边界。对象的边界通常由与......
  • iree 编译流程(2)——buildGlobalOptimizationPassPipeline
    buildGlobalOptimizationPassPipelineIREE::Util::createSimplifyGlobalAccessesPass这个pass主要做这几件事:将不可变globaltensor的load提前到了block的开头,将globaltensor的store安全地挪到block的结尾。进行以下化简:如果loadafterstore,则把load......
  • PyTorch下载完成之后无法使用GPU
    问题描述:测试代码如下:importtorchprint(torch.__version__)print(torch.cuda.is_available())print(torch.cuda.device_count())测试结果为false问题原因:使用清华源conda下载导致它会自动给你下载为cpu版问题解决:删除虚拟环境condaenvremove--namemyenv创建......
  • 如何在venv python中安装requirements.txt
    我是Python虚拟环境的初学者,在安装requirements.txt文件时遇到问题。问题是,当我运行命令来安装requirements.txt文件时,没有安装任何内容。平台:WindowsVS代码镜像如何解决这个问题?没有正确激活虚拟环境。请按照以下步骤操作:1.激活虚拟环境:在VSC......
  • 常用的数据集WebVision介绍和pytorch下的简单使用
    WebVision数据集介绍官方下载地址WebVision数据集常用于开集/闭集噪声学习、长尾噪声学习方法在真实数据集上的评估。根据[2]的统计,干净样本占70%,OOD噪声占25%,ID噪声占5%。由于数据集本身较大,论文中使用的都是其中很小的一部分,进入下载页面,选择《WebVisionDataset1.0》《Resi......
  • arduino 串口通信
    arduino串口通信1.编写arduino通信程序新建arduino代码管理空间,用于存放arduino的串口通信程序。rosnoetic@rosnoetic-VirtualBox:~$mkdirarduino_ws需求:通过串口,由arduino向计算机发送数据实现:新建arduino文件添加如下代码:/**需求:由arduino向PC发送数据:hellowo......
  • ComfyUI插件:ComfyUI layer style 节点(三)
    前言:学习ComfyUI是一场持久战,而ComfyUIlayerstyle是一组专为图片设计制作且集成了Photoshop功能的强大节点。该节点几乎将PhotoShop的全部功能迁移到ComfyUI,诸如提供仿照AdobePhotoshop的图层样式、提供调整颜色功能(亮度、饱和度、对比度等)、提供Mask辅助工具、提供图层合成......
  • Pytorch笔记|小土堆|P14-15|torchvision数据集使用、Dataloader使用
    学会看内置数据集的官方文档:https://pytorch.org/vision/stable/generated/torchvision.datasets.CIFAR10.html#torchvision.datasets.CIFAR10示例代码:importtorchvisionfromtorch.utils.tensorboardimportSummaryWriterfromtorchvisionimporttransforms#ToTensorte......
  • 3、Qt- 将ui文件转为py文件后运行py程序
    .ui转.py文件先将生成的.ui文件转为.py文件编辑.py文件#Formimplementationgeneratedfromreadinguifile'untitled.ui'##Createdby:PyQt6UIcodegenerator6.4.2##WARNING:Anymanualchangesmadetothisfilewillbelostwhenpyuic6is#runagain......
  • 2、Qt- 简单窗口的创建与运行ui文件
    认识QWidget和QLabel初识pyqt6语法fromPyQt6.QtWidgetsimportQApplication,QWidget,QLabelimportsys#创建应用对象app=QApplication(sys.argv)#sys.argv是一个列表,其中包含命令行参数。第一个参数是脚本名称,其余参数是命令行参数。类似shell脚本中的$1,$2,......