1.目的
最近团队有一个人脸识别的项目,想做一个网站界面来演示,同时使用了花生壳进行内网穿透,使得可以在其他设备访问该界面。
2.算法部分
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.pyplot as plt
import cv2
import numpy as np
import tensorflow as tf
import sys
sys.path.append(r'D:\study\EmotionDetection_RealTime-master\model')
# from model.ResNextT import ResNeXt50
from keras.layers import Layer
from keras.layers import Add, Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Multiply
from keras.models import Sequential
# 加载预训练的 VGG16 模型
class ECABlock(Layer):
def __init__(self, k=3, gamma=2, t=2):
super(ECABlock, self).__init__()
self.k = k
self.gamma = gamma
self.t = t
def build(self, input_shape):
self.conv1 = Conv2D(self.k, (1, 1), activation='relu')
self.conv2 = Conv2D(self.k, (1, 1), activation='relu')
self.pool = MaxPooling2D(pool_size=(self.t, self.t))
self.flatten = Flatten()
self.dense1 = Dense(units=self.k//self.gamma, activation='relu')
self.dense2 = Dense(units=self.k, activation='sigmoid')
self.multiply = Multiply()
def call(self, inputs):
x = self.conv1(inputs)
y = self.conv2(inputs)
y = self.pool(y)
y = self.flatten(y)
y = self.dense1(y)
y = self.dense2(y)
y = self.multiply([x, y])
return Add()([x, y])
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(48,48,1)))
model.add(ECABlock(k=3, gamma=2, t=2))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2),strides=(2,2)))
model.add(Dropout(0.5))
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2),strides=(2,2)))
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2),strides=(2,2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(7, activation='softmax'))
# 图像情感分类函数
def predict_emotion(image_path):
class_labels = ["Angry", "Disgusted", "Fearful", "Happy", "Neutral", "Sad", "Surprised"]
img = Image.open(image_path)
# 将图片转换为灰度图像
img_gray = img.convert('L')
# 将灰度图像调整为目标尺寸(48, 48)
img_resized = img_gray.resize((48, 48))
# 将调整后的灰度图像转换为 NumPy 数组
img_array = np.array(img_resized)
# 将数组转换为形状为(1, 48, 48, 1)
img_array = img_array.reshape((1, 48, 48, 1))
predictions = model.predict(img_array)
# 获取最大概率的类别索引
predicted_class_index = np.argmax(predictions)
# 获取对应的情感类别标签
emotion = class_labels[predicted_class_index]
return emotion
使用的resne50结合ECA注意力机制的模型,七分类任务。
3.网站部分
# Streamlit 应用程序
st.title('图像情感分类器')
uploaded_image = st.file_uploader("上传一张图片", type=['jpg', 'jpeg', 'png'])
if uploaded_image:
image_path = 'temp_image.jpg'
with open(image_path, 'wb') as f:
f.write(uploaded_image.read())
st.image(uploaded_image, caption='Uploaded Image', use_column_width=True)
emotion = predict_emotion(image_path)
st.write(f'该图片的情感类别为:{emotion}')
Streamlit 是一个用于构建数据应用程序的开源 Python 库。它使用户能够轻松创建具有交互性和可视化效果的 Web 应用程序,无需具备Web开发经验。使用Streamlit,您可以通过简单的Python脚本快速构建数据可视化、机器学习模型展示、数据分析工具等应用。
具体的命令,在终端(或者文件路径下)输入:
python -m streamlit run D:\study\EmotionDetection_RealTime-master\demo\01web.py
4.界面展示
终端在执行命令后,后输出构建的网站地址,同时会弹出构建的网站:
这个网站界面形式可以更改,对应的是3网站部分。具体功能是,点击上传按钮或者“Browse files”从电脑本地选择图片上传,经过短暂算法运行,会给出图片对应的情况类型。
上传图片
输出结果
5.内网穿透
这个网站地址是本地地址,只能通过本地电脑访问,其他设备无法访问,这里使用花生壳来实现内王穿透。
具体参考: