jotang招新8-2.1

目标:

复现此项目: 识别自己的表情符号

train.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import numpy as np
import cv2
from keras.emotion_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

train_dir = 'venv/train'
val_dir = 'venv/test'

# ImageDataGenerator图片处理生成器
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), # 默认图片大小为256*256,现在调整为48*48
batch_size=64,
color_mode="gray_framescale", # 颜色模式,默认RGB,设置为灰度为单通道的图片
class_mode='categorical') # 决定返回的标签数组的类型

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

# Sequential序贯模型
emotion_model = Sequential()
# 第一层需要指出输入的形状(样本数,行,列,通道数),只指出后三维即可,第一维按batch_size自动指定
# 卷积中滤波器的数量为32,即输出空间的维度
# kernel_size 卷积核大小

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')

# Using openCV haarcascade xml detect the bounding boxes of face in the webcam and predict the emotions:
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(lr=0.0001, decay=1e-6),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)
# 保存模型参数
emotion_model.save_weights('emotion_model.h5')

# start the webcam feed
cap = cv2.VideoCapture(0)
while True:
# Find haar cascade to draw bounding box around face
ret, frame = cap.read()
if not ret:
break

bounding_box = cv2.CascadeClassifier('/home/shivam/.local/lib/python3.6/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.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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 Dense, Dropout, Flatten
from keras.layers import Conv2D
from keras.optimizers import Adam
from keras.layers import MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator
import os

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')

cv2.ocl.setUseOpenCL(False)

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

emoji_dist = {0: "./emojis/angry.png", 2: "./emojis/disgusted.png", 2: "./emojis/fearful.png", 3: "./emojis/happy.png",
4: "./emojis/neutral.png", 5: "./emojis/sad.png", 6: "./emojis/surpriced.png"}

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


def show_vid():
# 打开摄像头
cap1 = cv2.VideoCapture(0)
if not cap1.isOpened():
print("cant open the camera1")

flag1, frame1 = cap1.read() # 捕获帧信息函数,flag1返回布尔值,frame1返回捕获的帧信息(图像)
frame1 = cv2.resize(frame1, (600, 500)) # 把frame1图片缩放

# 改为级联分类的地址
bounding_box = cv2.CascadeClassifier(
'D:/Anaconda/envs/pytorch/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
# 转为灰度图
gray_frame = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)

# # detectMultiScale(待检测图像,scaleFactor前后两次相继的扫描中搜索框的比例系数,默认为1.1即每次搜索框扩大10%,
# minNeighbors表示每一个目标至少要被检测到5次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸)) 返回人脸
num_faces = bounding_box.detectMultiScale(gray_frame, scaleFactor=1.3, minNeighbors=5)

for (x, y, w, h) in num_faces:
# 在frame上画矩形
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))
# putText添加文字 (图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细)
# 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 None:
print("Major error!")
elif flag1:
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)
lmain.after(10, show_vid)
if cv2.waitKey(1) & 0xFF == ord('q'):
exit()


def show_vid2():
# 读入的是array
frame2 = cv2.imread(emoji_dist[show_text[0]])
pic2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2RGB)
# 将array转换为image
img2 = Image.fromarray(frame2)
imgtk2 = ImageTk.PhotoImage(image=img2)
lmain2.imgtk2 = imgtk2
lmain3.configure(text=emotion_dict[show_text[0]], font=('arial', 45, 'bold'))

lmain2.configure(image=imgtk2)
lmain2.after(10, show_vid2)


if __name__ == '__main__':
root = tk.Tk()

img = ImageTk.PhotoImage(Image.open('data/logo.png'))

print(img)

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("1400x900+100+10")
root['bg'] = 'black'
exitbutton = Button(root, text='Quit', fg="red", command=root.destroy, font=('arial', 25, 'bold')).pack(side=BOTTOM)
show_vid()
show_vid2()
root.mainloop()


jotang招新8-2.1
http://example.com/2022/10/23/jotang招新8-2-1/
作者
YiZhi_w
发布于
2022年10月23日
许可协议