python之使用深度学习创建自己的表情符号

news2024/11/24 17:59:57

目录

    • 部署项目
      • 1、首先运行train.py训练模型
      • 2、接下运行gui.py测试
    • 一、使用 CNN 进行面部情绪识别
    • 二、GUI 代码和表情符号映射

在这个深度学习项目中,我们将对人类面部表情进行分类,以过滤和映射相应的表情符号或头像。

数据集(面部表情识别)由48*48像素的灰度人脸图像组成。图像居中并占据相等的空间。该数据集由以下类别的面部情绪组成:

0:生气
1:厌恶
2:壮举
3:快乐
4:悲伤
5:惊喜
6:自然

下载项目代码:click or click

我们将构建一个深度学习模型,从图像中对面部表情进行分类。然后,我们将分类的情感映射到表情符号或头像。

部署项目

没有相应的模块自己pip安装吧
在这里插入图片描述

1、首先运行train.py训练模型

等待训练完成生成emotion_model.h5
在这里插入图片描述

2、接下运行gui.py测试

请添加图片描述

一、使用 CNN 进行面部情绪识别

在以下步骤中,将构建卷积神经网络架构,并在数据集上训练模型FER2013以便从图像中进行情感识别。从上面的链接下载数据集。将其提取到具有单独训练和测试目录的数据文件夹中。

1、import

import numpy as np
import cv2
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D
from keras.optimizers import Adam

from keras.layers import MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator

2、初始化训练和验证生成器

train_dir = 'train'
val_dir = 'test'
train_datagen = ImageDataGenerator(rescale=1./255)
val_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        train_dir,
        target_size=(48,48),
        batch_size=64,
        color_mode="grayscale",
        class_mode='categorical')

validation_generator = val_datagen.flow_from_directory(
        val_dir,
        target_size=(48,48),
        batch_size=64,
        color_mode="grayscale",
        class_mode='categorical')

3、构建卷积网络架构

emotion_model = Sequential()

emotion_model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(48,48,1)))
emotion_model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))
emotion_model.add(Dropout(0.25))

emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))
emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))
emotion_model.add(Dropout(0.25))

emotion_model.add(Flatten())
emotion_model.add(Dense(1024, activation='relu'))
emotion_model.add(Dropout(0.5))
emotion_model.add(Dense(7, activation='softmax'))
# emotion_model.load_weights('emotion_model.h5')

4、编译和训练模型

cv2.ocl.setUseOpenCL(False)

emotion_dict = {0: "Angry", 1: "Disgusted", 2: "Fearful", 3: "Happy", 4: "Neutral", 5: "Sad", 6: "Surprised"}


emotion_model.compile(loss='categorical_crossentropy',optimizer=Adam(learning_rate=0.0001),metrics=['accuracy'])
emotion_model_info = emotion_model.fit_generator(
        train_generator,
        steps_per_epoch=28709 // 64,
        epochs=50,
        validation_data=validation_generator,
        validation_steps=7178 // 64)

5、保存模型权重

emotion_model.save_weights('emotion_model.h5')

6、使用openCV haarcascade xml检测网络摄像头中面部的边界框并预测情绪

cap = cv2.VideoCapture(0)
while True:
    # 查找haar级联以在面部周围绘制边界框
    ret, frame = cap.read()
    if not ret:
        break
        # 此处为自己文件夹下的haarcascade_frontalface_default.xml需要自己修改
    bounding_box = cv2.CascadeClassifier('E:\pycharm_python\\venv\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2gray_frame)
    num_faces = bounding_box.detectMultiScale(gray_frame,scaleFactor=1.3, minNeighbors=5)

    for (x, y, w, h) in num_faces:
        cv2.rectangle(frame, (x, y-50), (x+w, y+h+10), (255, 0, 0), 2)
        roi_gray_frame = gray_frame[y:y + h, x:x + w]
        cropped_img = np.expand_dims(np.expand_dims(cv2.resize(roi_gray_frame, (48, 48)), -1), 0)
        emotion_prediction = emotion_model.predict(cropped_img)
        maxindex = int(np.argmax(emotion_prediction))
        cv2.putText(frame, emotion_dict[maxindex], (x+20, y-60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)

    cv2.imshow('Video', cv2.resize(frame,(1200,860),interpolation = cv2.INTER_CUBIC))
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

二、GUI 代码和表情符号映射

创建一个名为 emojis 的文件夹,并将与数据集中七种情绪中的每一种对应的表情符号保存在一起
将以下代码粘贴到 gui.py 中并运行该文件

import tkinter as tk
from tkinter import *
import cv2
from PIL import Image, ImageTk
import numpy as np
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Flatten

cv2.ocl.setUseOpenCL(False)
emotion_dict = {0: "   Angry   ", 1: "Disgusted", 2: "  Fearful  ", 3: "   Happy   ", 4: "  Neutral  ",
                5: "    Sad    ", 6: "Surprised"}
#注意图片文件路径需要自己修改
emoji_dist = {0: "E:\\pycharm_python\\samil\\emojis\\angry.png", 1: "E:\\pycharm_python\\samil\\emojis\\disgusted.png",
              2: "E:\\pycharm_python\\samil\\emojis\\fearful.png", 3: "E:\\pycharm_python\\samil\\emojis\\happy.png",
              4: "E:\\pycharm_python\\samil\\emojis\\neutral.png", 5: "E:\\pycharm_python\\samil\\emojis\\sad.png",
              6: "E:\\pycharm_python\\samil\\emojis\\surpriced.png"}

emotion_model = Sequential()
emotion_model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(48, 48, 1)))
emotion_model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))
emotion_model.add(Dropout(0.25))
emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))
emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))
emotion_model.add(Dropout(0.25))
emotion_model.add(Flatten())
emotion_model.add(Dense(1024, activation='relu'))
emotion_model.add(Dropout(0.5))
emotion_model.add(Dense(7, activation='softmax'))
emotion_model.load_weights('emotion_model.h5')

global last_frame1
last_frame1 = np.zeros((480, 640, 3), dtype=np.uint8)
global cap1
show_text = [0]

def show_vid_combined():
    cap1 = cv2.VideoCapture(0)
    if not cap1.isOpened():
        print("摄像头没打开")
        return
    else:
        print('摄像头已经打开')

    flag1, frame1 = cap1.read()
    frame1 = cv2.resize(frame1, (600, 500))

    bounding_box = cv2.CascadeClassifier(
        'E:\\pycharm_python\\venv\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml')
    gray_frame = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
    num_faces = bounding_box.detectMultiScale(gray_frame, scaleFactor=1.3, minNeighbors=5)

    for (x, y, w, h) in num_faces:
        cv2.rectangle(frame1, (x, y - 50), (x + w, y + h + 10), (255, 0, 0), 2)
        roi_gray_frame = gray_frame[y:y + h, x:x + w]
        cropped_img = np.expand_dims(np.expand_dims(cv2.resize(roi_gray_frame, (48, 48)), -1), 0)
        prediction = emotion_model.predict(cropped_img)

        maxindex = int(np.argmax(prediction))
        cv2.putText(frame1, emotion_dict[maxindex], (x + 20, y - 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2,
                    cv2.LINE_AA)
        show_text[0] = maxindex

    if flag1 is not None:
        global last_frame1
        last_frame1 = frame1.copy()
        pic = cv2.cvtColor(last_frame1, cv2.COLOR_BGR2RGB)
        img = Image.fromarray(pic)
        imgtk = ImageTk.PhotoImage(image=img)
        lmain.imgtk = imgtk
        lmain.configure(image=imgtk)

    cap1.release()

    # 调度 show_vid_combined
    root.after(10, show_vid_combined)

def show_vid2():
    print("show_vid2 called")  
    if show_text[0] in emoji_dist:
        frame2 = cv2.imread(emoji_dist[show_text[0]])
        if frame2 is not None:
            print("Frame loaded successfully")  
            pic2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2RGB)
            img2 = Image.fromarray(pic2)
            imgtk2 = ImageTk.PhotoImage(image=img2)
            lmain2.imgtk2 = imgtk2
            lmain3.configure(text=emotion_dict[show_text[0]], font=('arial', 45, 'bold'))
            lmain2.configure(image=imgtk2)
        else:
            print('无法加载图像')
    else:
        print('表情文件不存在')

    root.after(10, show_vid2)



if __name__ == '__main__':
    root = tk.Tk()
    img = ImageTk.PhotoImage(Image.open("logo.png"))
    heading = Label(root, image=img, bg='black')

    heading.pack()
    heading2 = Label(root, text="Photo to Emoji", pady=20, font=('arial', 45, 'bold'), bg='black', fg='#CDCDCD')

    heading2.pack()
    lmain = tk.Label(master=root, padx=50, bd=10)
    lmain2 = tk.Label(master=root, bd=10)

    lmain3 = tk.Label(master=root, bd=10, fg="#CDCDCD", bg='black')
    lmain.pack(side=LEFT)
    lmain.place(x=50, y=250)
    lmain3.pack()
    lmain3.place(x=960, y=250)
    lmain2.pack(side=RIGHT)
    lmain2.place(x=900, y=350)

    root.title("Photo To Emoji")
    root.geometry("1400x800+100+10")
    root['bg'] = 'black'
    exitbutton = Button(root, text='Quit', fg="red", command=root.destroy, font=('arial', 25, 'bold')).pack(side=BOTTOM)

    # 调度 show_vid_combined
    root.after(10, show_vid_combined)
    root.after(10, show_vid2)
    root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1214184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

提效神器!10%标注数据,比肩全量标注的模型效果!

不知道大家有没有遇到过数据标注成本高、周期长的困扰,有没有那么一种可能,精心标注少量的数据,配合大量的无标注数据,就能达到比肩全量标注的模型精度呢?是的,PaddleX就带来了这样一款提效神器——大模型半…

超级干货!如何挖公益SRC实战/SQL注入

目录 一、信息收集 二、实战演示 三、使用sqlmap进行验证 四、总结 一、信息收集 1.查找带有ID传参的网站(可以查找sql注入漏洞) inurl:asp idxx 2.查找网站后台(多数有登陆框,可以查找弱口令,暴力破解等漏洞&…

第一百七十四回 如何创建扇形渐变背景

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在 上一章回中介绍了"如何创建线性渐变背景"相关的内容,本章回中将介绍" 如何创建扇形渐变背景"。闲话休提,让我们一起Talk Flutter吧。 …

打开GeoTIFF文件失败:Unknown field with tag

用QGIS输出的数据类型为UInt16的TIFF文件,无法在GIMP中打开。 GIMP消息提示: 调查 用ImageMagick打开TIFF文件,虽然会出现警告,但是最终还是打开了: 在ImageMagick中重新保存后,就可以用GIMP打开了。使用…

Mapstruct 搭配MP分页食用 - 参考自ballcat项目

参考自 ballcat 一键抵达: Gitee GitHub 场景 使用MyBatis Plus的selectPage方法进行分页查询之后,如果需要将Entity对象转换为Vo对象,需要从Page对象中取出集合列表,手动转换成Vo集合列表数据重新放进Page对象中。 取出集合 设置…

使用postman测试

第一步: 第二步: 第三步:添加请求 第四步:填写请求 代码实现自动关联的位置: 为相关联的接口设置环境: 使用设置的环境变量: 参数化实现测试:测试脚本中仅测试数据不一样&#xff…

[答疑]改善系统的性能,用得着业务建模吗

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 第五元素 2023-10-27 22:02 潘老师,请教一个实践中遇到的问题: 假设生产人员使用某个工具处理数据,需要10天时间;现在改进了这个工具…

Java排序算法之堆排序

图解 堆排序是一种常见的排序算法,它借助了堆这种数据结构。堆是一种完全二叉树,它可以分为两种类型:最大堆和最小堆。在最大堆中,每个结点的值都大于等于它的子结点的值,而在最小堆中,每个结点的值都小于等…

SpringSecurity6从入门到上天系列第六篇:解决这个问题为什么在引入SpringSecurity之后所有的请求都需要先做登录认证才可以进行访问呢

文章目录 问题引入 1:问题阐述 2:问题分析 一:从SpringBoot的自动装配 1:SpringBootApplication介绍 2:自动装配的核心方法 3:核心方法的调用路径 4:SpringSecurity核心配置 5&#xf…

PMP备考短期极限上岸攻略!

作为一位通过PMP考试成功上岸的3A人士,下面的文章包含了所有PMP考试的实用知识,是一本适合初学者的PMP备考攻略手册。如果你有意向了解或者报考PMP考试,这篇文章肯定会对你有很大的帮助! 对于新手第一个需要知道的就是PMP是什么&…

【python】—— 控制语句和组合数据类型(其一)

🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL&#xff1a…

Flume(一)【Flume 概述】

前言 今天实在不知道学点什么好了,早上学了3个多小时的 Flink ,整天只学一门技术是很容易丧失兴趣的。那就学点新的东西 Flume,虽然 Kafka 还没学完,但是大数据生态圈的基础组件也基本就剩这倆了。 Flume 概述 生产环境中的数据一…

Sql Prompt 10下载安装图文教程

在操作过程中,请暂时关闭你的防病毒软件,以免其误报导致操作失败。 资源 SQL Prompt 10 https://www.aliyundrive.com/s/QuMWkvE1Sv6 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看&…

20 - 欲知JVM调优先了解JVM内存模型

从今天开始,我将和你一起探讨 Java 虚拟机(JVM)的性能调优。JVM 算是面试中的高频问题了,通常情况下总会有人问到:请你讲解下 JVM 的内存模型,JVM 的性能调优做过吗? 1、为什么 JVM 在 Java 中…

Qt高级--(2)自定义标题栏

自定义标题栏 功能点 1.标题栏中最外层布局器使用水平布局器。 2.导航按钮、工具按钮和窗口功能按钮都是用水平布局器,边距和间隔可根据实际情况设置。 3.编写 QSS 样式,并将样式设置到窗口控件中。 4.实现最小化、最大化和关闭窗口按钮功能。 5.实现鼠…

mysql数据库,sql语句中连接查询,连表查询,内连接,外连接,左外连接,右外连接,inner join、left join、right join,全连接

连表查询 现有多张表:员工表 emp(员工编号、姓名、工资、部门号、经理编号)、部门表 dept(部门号、部门名称、部门位置)、工资等级表 salgrade(等级、工资下限、工资上限) 连接查询:…

ClassLoader

Java /Android 默认ClassLoader是PathClassLoader Android 的 PathClassLoader 和DexClassLoader 都是BaseDexClassLoader的子类 BaseClassLoader是ClassLoader的子类,通过loadClass方法加载,Android将Java的ClassLoader简化了,第二个参数arg2 无效 loadClass 通过 findLoad…

搭建知识付费系统的最佳实践是什么

在数字化时代,搭建一个高效且用户友好的知识付费系统是许多创业者和内容创作者追求的目标。本文将介绍一些搭建知识付费系统的最佳实践,同时提供一些基本的技术代码示例,以帮助你快速入门。 1. 选择合适的技术栈: 搭建知识付费…

YOLO目标检测——烟叶病害检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用:烟叶病虫害防治数据集说明:烟叶病害检测数据集,真实场景的高质量图片数据,数据场景丰富,类别分为:轻度病虫、中度病虫、高度病虫标签说明:使用lableimg标注软件标注,标…

微信群BUG大揭秘!开启身份切换神器

前言 最近微信群里出现了一个神秘的BUG,普通群成员竟然可以艾特全体成员。今天,就让我们一起揭秘这个令人震惊的微信群普通成员可全体成员的BUG 复现步骤 复现步骤也很简单,前提条件就是要在PC客户端操作!首先得有个属于自己的群…