Python基于keras训练如何实现微笑识别
发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要介绍Python基于keras训练如何实现微笑识别,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、数据预处理实验数据来自genki4k提取含有完整人脸的图片def
千家信息网最后更新 2026年11月04日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安全错误
数据库的锁怎样保障安全
手磨咖啡
有格互联网科技
互联网金融与金融科技
万易互联网科技
科技创新互联网企业
睿民互联网科技
互联网养老 桔豆科技
左右互联网络科技
佩信高科技互联网
互联网科技公司需要的职位
互联网企业和科技型企业
开一家科技互联网公司需要多少钱
晋城互联网科技
世界互联网领先科技成果获奖
互联网方面的科技前沿
互联网科技实习生岗位
中国互联网公司的科技投入
互联网科技创业计划的风险分析
伍佰万互联网科技是干嘛的
山东亿川互联网科技有限责任公司
互联网佳科技有限公司
中国互联网科技工作委员会毛军
互联网科技活动banner
居家互联网科技有限公司
互联网还是高科技吗
互联网5g黑科技有哪些
2021互联网科技公司排名
杭州披云加互联网科技有限公司
绵阳真晨互联网科技有限公司
互联网的黑科技实验室