Python基于keras训练如何实现微笑识别
发表于:2025-02-10 作者:千家信息网编辑
千家信息网最后更新 2025年02月10日,这篇文章主要介绍Python基于keras训练如何实现微笑识别,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、数据预处理实验数据来自genki4k提取含有完整人脸的图片def
千家信息网最后更新 2025年02月10日Python基于keras训练如何实现微笑识别
这篇文章主要介绍Python基于keras训练如何实现微笑识别,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
一、数据预处理
实验数据来自genki4k
提取含有完整人脸的图片
def init_file(): num = 0 bar = tqdm(os.listdir(read_path)) for file_name in bar: bar.desc = "预处理图片: " # a图片的全路径 img_path = (read_path + "/" + file_name) # 读入的图片的路径中含非英文 img = cv2.imdecode(np.fromfile(img_path, dtype=np.uint8), cv2.IMREAD_UNCHANGED) # 获取图片的宽高 img_shape = img.shape img_height = img_shape[0] img_width = img_shape[1] # 用来存储生成的单张人脸的路径 # dlib检测 dets = detector(img, 1) for k, d in enumerate(dets): if len(dets) > 1: continue num += 1 # 计算矩形大小 # (x,y), (宽度width, 高度height) # pos_start = tuple([d.left(), d.top()]) # pos_end = tuple([d.right(), d.bottom()]) # 计算矩形框大小 height = d.bottom() - d.top() width = d.right() - d.left() # 根据人脸大小生成空的图像 img_blank = np.zeros((height, width, 3), np.uint8) for i in range(height): if d.top() + i >= img_height: # 防止越界 continue for j in range(width): if d.left() + j >= img_width: # 防止越界 continue img_blank[i][j] = img[d.top() + i][d.left() + j] img_blank = cv2.resize(img_blank, (200, 200), interpolation=cv2.INTER_CUBIC) # 保存图片 cv2.imencode('.jpg', img_blank)[1].tofile(save_path + "/" + "file" + str(num) + ".jpg") logging.info("一共", len(os.listdir(read_path)), "个样本") logging.info("有效样本", num)
二、训练模型
创建模型
# 创建网络def create_model(): model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Flatten()) model.add(layers.Dropout(0.5)) model.add(layers.Dense(512, activation='relu')) model.add(layers.Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc']) return model
训练模型
# 训练模型def train_model(model): # 归一化处理 train_datagen = ImageDataGenerator( rescale=1. / 255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, ) test_datagen = ImageDataGenerator(rescale=1. / 255) train_generator = train_datagen.flow_from_directory( # This is the target directory train_dir, # All images will be resized to 150x150 target_size=(150, 150), batch_size=32, # Since we use binary_crossentropy loss, we need binary labels class_mode='binary') validation_generator = test_datagen.flow_from_directory( validation_dir, target_size=(150, 150), batch_size=32, class_mode='binary') history = model.fit_generator( train_generator, steps_per_epoch=60, epochs=12, validation_data=validation_generator, validation_steps=30) # 保存模型 save_path = "../output/model" if not os.path.exists(save_path): os.makedirs(save_path) model.save(save_path + "/smileDetect.h6") return history
训练结果
准确率
丢失率
训练过程
三、预测
通过读取摄像头内容进行预测
def rec(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) dets = detector(gray, 1) if dets is not None: for face in dets: left = face.left() top = face.top() right = face.right() bottom = face.bottom() cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0), 2) img1 = cv2.resize(img[top:bottom, left:right], dsize=(150, 150)) img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB) img1 = np.array(img1) / 255. img_tensor = img1.reshape(-1, 150, 150, 3) prediction = model.predict(img_tensor) if prediction[0][0] > 0.5: result = 'unsmile' else: result = 'smile' cv2.putText(img, result, (left, top), font, 2, (0, 255, 0), 2, cv2.LINE_AA) cv2.imshow('Video', img)while video.isOpened(): res, img_rd = video.read() if not res: break rec(img_rd) if cv2.waitKey(1) & 0xFF == ord('q'): break
效果
四、源代码
pretreatment.py
import dlib # 人脸识别的库dlibimport numpy as np # 数据处理的库numpyimport cv2 # 图像处理的库OpenCvimport osimport shutilfrom tqdm import tqdmimport logging# dlib预测器detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor('../resources/shape_predictor_68_face_landmarks.dat')# 原图片路径read_path = "../resources/genki4k/files"# 提取人脸存储路径save_path = "../output/genki4k/files"if not os.path.exists(save_path): os.makedirs(save_path)# 新的数据集data_dir = '../resources/data'if not os.path.exists(data_dir): os.makedirs(data_dir)# 训练集train_dir = data_dir + "/train"if not os.path.exists(train_dir): os.makedirs(train_dir)# 验证集validation_dir = os.path.join(data_dir, 'validation')if not os.path.exists(validation_dir): os.makedirs(validation_dir)# 测试集test_dir = os.path.join(data_dir, 'test')if not os.path.exists(test_dir): os.makedirs(test_dir)# 初始化训练数据def init_data(file_list): # 如果不存在文件夹则新建 for file_path in file_list: if not os.path.exists(file_path): os.makedirs(file_path) # 存在则清空里面所有数据 else: for i in os.listdir(file_path): path = os.path.join(file_path, i) if os.path.isfile(path): os.remove(path)def init_file(): num = 0 bar = tqdm(os.listdir(read_path)) for file_name in bar: bar.desc = "预处理图片: " # a图片的全路径 img_path = (read_path + "/" + file_name) # 读入的图片的路径中含非英文 img = cv2.imdecode(np.fromfile(img_path, dtype=np.uint8), cv2.IMREAD_UNCHANGED) # 获取图片的宽高 img_shape = img.shape img_height = img_shape[0] img_width = img_shape[1] # 用来存储生成的单张人脸的路径 # dlib检测 dets = detector(img, 1) for k, d in enumerate(dets): if len(dets) > 1: continue num += 1 # 计算矩形大小 # (x,y), (宽度width, 高度height) # pos_start = tuple([d.left(), d.top()]) # pos_end = tuple([d.right(), d.bottom()]) # 计算矩形框大小 height = d.bottom() - d.top() width = d.right() - d.left() # 根据人脸大小生成空的图像 img_blank = np.zeros((height, width, 3), np.uint8) for i in range(height): if d.top() + i >= img_height: # 防止越界 continue for j in range(width): if d.left() + j >= img_width: # 防止越界 continue img_blank[i][j] = img[d.top() + i][d.left() + j] img_blank = cv2.resize(img_blank, (200, 200), interpolation=cv2.INTER_CUBIC) # 保存图片 cv2.imencode('.jpg', img_blank)[1].tofile(save_path + "/" + "file" + str(num) + ".jpg") logging.info("一共", len(os.listdir(read_path)), "个样本") logging.info("有效样本", num)# 划分数据集def divide_data(file_path, message, begin, end): files = ['file{}.jpg'.format(i) for i in range(begin, end)] bar = tqdm(files) bar.desc = message for file in bar: src = os.path.join(save_path, file) dst = os.path.join(file_path, file) shutil.copyfile(src, dst)if __name__ == "__main__": init_file() positive_train_dir = os.path.join(train_dir, 'smile') negative_train_dir = os.path.join(train_dir, 'unSmile') positive_validation_dir = os.path.join(validation_dir, 'smile') negative_validation_dir = os.path.join(validation_dir, 'unSmile') positive_test_dir = os.path.join(test_dir, 'smile') negative_test_dir = os.path.join(test_dir, 'unSmile') file_list = [positive_train_dir, positive_validation_dir, positive_test_dir, negative_train_dir, negative_validation_dir, negative_test_dir] init_data(file_list) divide_data(positive_train_dir, "划分训练集正样本", 1, 1001) divide_data(negative_train_dir, "划分训练集负样本", 2200, 3200) divide_data(positive_validation_dir, "划分验证集正样本", 1000, 1500) divide_data(negative_validation_dir, "划分验证集负样本", 3000, 3500) divide_data(positive_test_dir, "划分测试集正样本", 1500, 2000) divide_data(negative_test_dir, "划分测试集负样本", 2800, 3500)
train.py
import osfrom keras import layersfrom keras import modelsfrom tensorflow import optimizersimport matplotlib.pyplot as pltfrom keras.preprocessing.image import ImageDataGeneratortrain_dir = "../resources/data/train"validation_dir = "../resources/data/validation"# 创建网络def create_model(): model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Flatten()) model.add(layers.Dropout(0.5)) model.add(layers.Dense(512, activation='relu')) model.add(layers.Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc']) return model# 训练模型def train_model(model): # 归一化处理 train_datagen = ImageDataGenerator( rescale=1. / 255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, ) test_datagen = ImageDataGenerator(rescale=1. / 255) train_generator = train_datagen.flow_from_directory( # This is the target directory train_dir, # All images will be resized to 150x150 target_size=(150, 150), batch_size=32, # Since we use binary_crossentropy loss, we need binary labels class_mode='binary') validation_generator = test_datagen.flow_from_directory( validation_dir, target_size=(150, 150), batch_size=32, class_mode='binary') history = model.fit_generator( train_generator, steps_per_epoch=60, epochs=12, validation_data=validation_generator, validation_steps=30) # 保存模型 save_path = "../output/model" if not os.path.exists(save_path): os.makedirs(save_path) model.save(save_path + "/smileDetect.h6") return history# 展示训练结果def show_results(history): # 数据增强过后的训练集与验证集的精确度与损失度的图形 acc = history.history['acc'] val_acc = history.history['val_acc'] loss = history.history['loss'] val_loss = history.history['val_loss'] # 绘制结果 epochs = range(len(acc)) plt.plot(epochs, acc, 'bo', label='Training acc') plt.plot(epochs, val_acc, 'b', label='Validation acc') plt.title('Training and validation accuracy') plt.legend() plt.figure() plt.plot(epochs, loss, 'bo', label='Training loss') plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and validation loss') plt.legend() plt.show()if __name__ == "__main__": model = create_model() history = train_model(model) show_results(history)
predict.py
import osfrom keras import layersfrom keras import modelsfrom tensorflow import optimizersimport matplotlib.pyplot as pltfrom keras.preprocessing.image import ImageDataGeneratortrain_dir = "../resources/data/train"validation_dir = "../resources/data/validation"# 创建网络# 检测视频或者摄像头中的人脸import cv2from keras.preprocessing import imagefrom keras.models import load_modelimport numpy as npimport dlibfrom PIL import Imagemodel = load_model('../output/model/smileDetect.h6')detector = dlib.get_frontal_face_detector()video = cv2.VideoCapture(0)font = cv2.FONT_HERSHEY_SIMPLEXdef rec(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) dets = detector(gray, 1) if dets is not None: for face in dets: left = face.left() top = face.top() right = face.right() bottom = face.bottom() cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0), 2) img1 = cv2.resize(img[top:bottom, left:right], dsize=(150, 150)) img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB) img1 = np.array(img1) / 255. img_tensor = img1.reshape(-1, 150, 150, 3) prediction = model.predict(img_tensor) if prediction[0][0] > 0.5: result = 'unsmile' else: result = 'smile' cv2.putText(img, result, (left, top), font, 2, (0, 255, 0), 2, cv2.LINE_AA) cv2.imshow('Video', img)while video.isOpened(): res, img_rd = video.read() if not res: break rec(img_rd) if cv2.waitKey(1) & 0xFF == ord('q'): breakvideo.release()cv2.destroyAllWindows()
以上是"Python基于keras训练如何实现微笑识别"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!
训练
图片
样本
人脸
数据
路径
模型
大小
矩形
处理
生成
验证
内容
图像
结果
网络
存储
检测
测试
预处理
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全4a管理发展
英国大学网络安全硕士专业
网络安全专业应考取什么证书
linux局域网服务器聊天软件
创造与魔法人数最少的服务器
中小学网络安全知识教育视频
广东服务器机柜咨询报价
网络安全测试起步
特斯拉有数据库吗
如何网络安全管理工作
搜索引擎 数据库
制定网络安全法的目的
ps4怎样调节服务器
电脑能上网游戏无法连接服务器
捷亚网络技术有限公司
mdb数据库查询
手机经常接收不到服务器是咋回事
银行有啥数据库
我的世界创造系列服务器
网络安全博览会历史
绝地求生国际服推荐的服务器
养护公司网络安全和信息化
广州应用软件开发中心
数据库 测试 工具 国产
职称计算机考试数据库
网络安全与数据挖掘平台
魔兽世界转服务器会不会丢东西
数据库技术应用实验教程
oracle 数据库信息
isa缓存服务器