Emojify – Create your own emoji with Deep Learning


通过深度学习创建你自己的表情

原文与源码链接

https://data-flair.training/blogs/create-emoji-with-deep-learning/

数据集下载地址

https://www.kaggle.com/datasets/msambare/fer2013?resource=download

代码结构

下载好源码与数据集解压之后,将各文件按以下结构存放
在这里插入图片描述

注意事项

1.运行train.py时

报一些No Moudle named…的错误,使用pip install …安装(即,缺啥装啥;如,pip install keras,pip install tensorflow)

代码中:bounding_box = cv2.CascadeClassifier(‘/home/shivam/.local/lib/python3.6/site-packages/cv2/data/haarcascade_frontalface_default.xml’)也需要修改,

括号里面的地址需要改成自己的anaconda虚拟环境的当前地址。比如我的改成:

bounding_box = cv2.CascadeClassifier(‘E:\anaconda\envs\pytorch\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml’)
这个虚拟环境地址在gui.py里也有

2.报错

2.1 报错1

from keras.emotion_models import Sequential ModuleNotFoundError: No module named ‘keras.emotion_models’

解决办法

将from keras.emotion_models import Sequential
修改为
from keras.models import Sequential

2.2 报错2

ValueError: (‘Invalid color mode:’, ‘gray_framescale’, ‘; expected “rgb”, “rgba”, or “grayscale”.’)

解决方法

train_generator 和 validation_generator里面的color_mode的参数进行修改,改为 grayscale。
即改成:color_mode=“grayscale”

2.3 报错3

module ‘cv2’ has no attribute ‘COLOR_BGR2gray_frame’

解决办法

将gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2gray_frame)
改为gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

2.4 报错4

ValueError: decay is deprecated in the new Keras optimizer, pleasecheck the docstring for valid arguments, or use the legacy optimizer, e.g., tf.keras.optimizers.legacy.Adam.

解决办法

将from keras.optimizers import Adam
改为from keras.optimizers import legacy
将emotion_model.compile(loss=‘categorical_crossentropy’,optimizer=Adam(lr=0.0001, decay=1e-6),metrics=[‘accuracy’])
改为emotion_model.compile(loss=‘categorical_crossentropy’,optimizer=legacy.Adam(learning_rate=0.0001, decay=1e-6),metrics=[‘accuracy’])
Adam前加legacy.
lr改learning_rate

3.等待训练

在这里插入图片描述
训练结束,会自动弹出电脑摄像头的检测框(前提是允许摄像头弹出),检测你的面部表情,你可以做一些表情看看检测情况,想退出的话,按 q 退出。

train.py代码流程

# 导包
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.optimizers import legacy
from keras.layers import MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator

# 定义训练数据集的目录
train_dir = 'data/train'

# 定义验证数据集的目录
val_dir = 'data/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')            # 使用分类标签

# 创建一个序列模型
emotion_model = Sequential()

# 添加一个卷积层,32个3x3的卷积核,使用ReLU激活函数,输入图像大小为48x48,通道数为1
emotion_model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(48,48,1)))

# 添加一个卷积层,64个3x3的卷积核,使用ReLU激活函数
emotion_model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))

# 添加最大池化层,使用2x2的池化窗口
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))

# 添加一个Dropout层,随机丢弃25%的输入单元,用于防止过拟合
emotion_model.add(Dropout(0.25))

# 添加一个卷积层,128个3x3的卷积核,使用ReLU激活函数
emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))

# 添加一个最大池化层,使用2x2的池化窗口
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))

# 添加一个卷积层,128个3x3的卷积核,使用ReLU激活函数
emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))

# 添加一个最大池化层,使用2x2的池化窗口
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))

# 添加一个Dropout层,随机丢弃50%的输入单元,用于防止过拟合
emotion_model.add(Dropout(0.5))

# 将多维数据展开为一维数据
emotion_model.add(Flatten())

# 添加一个全连接层,包含1024个神经元,使用ReLU激活函数
emotion_model.add(Dense(1024, activation='relu'))

# 添加一个Dropout层,随机丢弃50%的输入单元,用于防止过拟合
emotion_model.add(Dropout(0.5))

# 添加一个全连接层,包含7个神经元,使用softmax激活函数,用于多分类任务
emotion_model.add(Dense(7, activation='softmax'))

# 加载预训练的权重(如果有的话)
# emotion_model.load_weights('emotion_model.h5')

# 禁用OpenCL加速,避免在某些系统上出现问题
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=legacy.Adam(learning_rate=0.0001, decay=1e-6),
                      metrics=['accuracy'])

# 使用生成器训练情绪识别模型
emotion_model_info = emotion_model.fit_generator(
        train_generator,                                           # 训练数据生成器
        steps_per_epoch=28709 // 64,                               # 每个epoch的步数
        epochs=50,                                                 # 训练迭代的次数
        validation_data=validation_generator,                      # 验证数据生成器
        validation_steps=7178 // 64)                                # 验证数据的步数

# 保存训练好的情绪识别模型的权重
emotion_model.save_weights('emotion_model.h5')

这段代码编译了情绪识别模型,使用categorical_crossentropy作为损失函数,Adam优化器进行模型优化,同时监测模型的准确率。然后使用fit_generator方法来训练模型,指定了训练数据生成器、每个epoch的步数、迭代次数、验证数据生成器以及验证数据的步数。最后,保存了训练好的模型权重到文件emotion_model.h5。

# 启动摄像头
cap = cv2.VideoCapture(0)

# 循环捕获视频帧
while True:
    # 读取视频帧
    ret, frame = cap.read()
    
    # 检查是否成功读取帧
    if not ret:
        break
    
    # 加载人脸检测器的Haar级联分类器
    bounding_box = cv2.CascadeClassifier('E:\\anaconda\\envs\\pytorch\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml')
    
    # 将视频帧转换为灰度图像
    gray_frame = cv2.cvtColor(frame, 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(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))
    
    # 等待按键输入,按下 'q' 键退出循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放摄像头
cap.release()

# 关闭所有窗口
cv2.destroyAllWindows()

这段代码启动了摄像头,并使用循环不断读取摄像头的帧。每一帧通过Haar级联分类器检测人脸,并在检测到的人脸周围绘制矩形框。然后提取人脸区域进行情绪识别预测,并在视频帧上显示出预测的情绪标签。通过按下 ‘q’ 键退出循环,释放摄像头资源,并关闭所有窗口。

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐丶晚笙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值