温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :)
1. 项目简介
面部关键点识别是指从图像中自动定位出人脸上的特定部位(如眼睛、鼻子、嘴巴等)的位置。随着计算机视觉技术的发展,面部关键点识别已经成为许多应用的核心技术之一,如面部识别、表情分析、虚拟试妆等。传统的基于特征的方法在光照变化、遮挡、姿态等方面表现不佳,而深度学习方法因其强大的特征表示能力和适应性,在这一领域取得了显著的进步。本项目利用 Tensorflow 和 Keras 构建卷积神经网络,利用扩充的数据集完成模型的训练、验证和测试,面部关键点识别像素级误差为0.95,小于1个像素点。并利用 Flask + Bootstrap 框架搭建交互式分析平台,通过上传待测试人脸图像,调用模型,完成关键点的识别和标绘。
B站视频详情及代码下载:基于深度学习的面部关键点识别系统_哔哩哔哩_bilibili
基于深度学习的面部关键点识别系统
2. 面部关键点数据集读取与预处理
人脸关键点检测是指给定人脸图像,定位出人脸面部的关键点,包括眉毛、眼睛、鼻子、嘴巴、脸部轮廓区域的点,由于受到姿态和遮挡等因素的影响,人脸关键点检测是一个富有挑战性的任务。人脸关键点是人脸各个部位的重要特征点,通常是轮廓点与角点。本数据集的面部关键点包括左右眼、眉毛、鼻子、嘴巴的共计30个关键点位:
......
imag = []
for i in range(0,7049):
img = train_data['Image'][i].split(' ')
img = ['0' if x == '' else x for x in img]
imag.append(img)
image_list = np.array(imag,dtype = 'float')
X_train = image_list.reshape(-1,96,96,1)
training = train_data.drop('Image',axis = 1)
y_train = []
for i in range(0,7049):
y = training.iloc[i,:]
y_train.append(y)
y_train = np.array(y_train,dtype = 'float')
def plot_image(image, keypoint, axis, title):
image = image.reshape(96,96)
axis.imshow(image, cmap='gray')
axis.scatter(keypoint[0::2], keypoint[1::2], marker='*', s=30, c='red')
plt.title(title)
3. 数据增强与样本扩充
原始样本只包含7049条,样本过少,难以训练大规模参数的神经网络,针对人脸关键点数据,可以采用平移、旋转、像素增强等策略,进行样本的扩充:
python
import numpy as np
import cv2
from math import cos, sin, pi
def rotate_augmentation(images, keypoints):
rotated_images = [] # 用于存储旋转后的图像列表
rotated_keypoints = [] # 用于存储旋转后的关键点列表
print("正在增强的角度(度): ") # 打印增强角度的标题
for angle in rotation_angles: # 对预定义的一系列旋转角度进行循环
for angle in [angle, -angle]: # 使用角度及其相反数进行增强
print(f'{angle}', end=' ') # 打印当前使用的角度
M = cv2.getRotationMatrix2D((48,48), angle, 1.0) # 获取给定角度下的旋转矩阵
angle_rad = -angle * pi / 180. # 将角度从度转换为弧度
# 对数据集中的每张图像应用旋转
for image in images:
rotated_image = cv2.warpAffine(image, M, (96,96), flags=cv2.INTER_CUBIC) # 应用旋转
rotated_images.append(rotated_image) # 将旋转后的图像添加到列表中
# 对每个关键点集应用旋转公式
for keypoint in keypoints:
rotated_keypoint = keypoint - 48. # 将关键点围绕原点居中
# 对每个坐标对应用旋转公式
for idx in range(0, len(rotated_keypoint), 2):
x, y = rotated_keypoint[idx], rotated_keypoint[idx + 1]
rotated_keypoint[idx] = x * cos(angle_rad) - y * sin(angle_rad)
rotated_keypoint[idx + 1] = x * sin(angle_rad) + y * cos(angle_rad)
rotated_keypoint += 48. # 将关键点移回原来的位置
rotated_keypoints.append(rotated_keypoint) # 将旋转后关键点添加到列表中
# 将旋转后的图像列表重塑成形状为 (-1, 96, 96, 1) 的张量
rotated_images = np.reshape(rotated_images, (-1, 96, 96, 1))
return rotated_images, rotated_keypoints # 返回增强后的图像和关键点
完成扩充后,训练集样本数达到了 21147 条。旋转后的样本,关键点位也同时进行了偏移。
4. 卷积神经网络模型构建
卷积神经网络(Convolutional Neural Networks, CNN)是一种专门用于处理具有类似网格结构的数据的深度学习模型,例如图像。CNN在计算机视觉领域取得了巨大的成功,尤其是在图像识别、目标检测和图像生成等方面。
关键特点:
- 局部感受野:CNN通过卷积层捕捉输入数据的局部特征,每个神经元只与输入数据的一个局部区域相连接。
- 权重共享:在卷积层中,同一个卷积核的权重在整个输入数据上共享,这减少了模型参数的数量,提高了训练效率。
- 池化层:CNN通常在卷积层之后使用池化层来降低特征维度,减少计算量,同时保持特征的不变性。
- 层次结构:CNN通过多个卷积和池化层的堆叠,逐渐提取从低级到高级的特征
Tensorflow是一个开源的机器学习框架,而Keras是一个高级API,它可以运行在Tensorflow之上,使得构建和训练神经网络变得更加简单。
python
model = Sequential()
model.add(Convolution2D(32, (3,3), padding='same', use_bias=False, input_shape=(96,96,1)))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())
model.add(Convolution2D(32, (3,3), padding='same', use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())
model.add(MaxPool2D(pool_size=(2, 2)))
......
model.add(Convolution2D(128, (3,3),padding='same', use_bias=False))
# model.add(BatchNormalization())
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())
......
model.add(Flatten())
model.add(Dense(512,activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(30))
model.summary()
model.compile(optimizer='adam',
loss='mean_squared_error',
metrics=['mae'])
5. 模型训练与验证
利用切分的训练集进行模型的训练,验证集进行模型的验证评估,并保存 val_mae 最低的模型权重:
python
checkpoint = ModelCheckpoint('save_models/best_model.h5', monitor='val_mae', verbose=1, mode='min',save_best_only=True)
early = EarlyStopping(monitor="val_mae", mode="min",restore_best_weights=True, patience=5)
lrp_reducer = ReduceLROnPlateau(monitor='val_loss', factor=lrp_factor, patience=lrp_patience, verbose=1)
callbacks_list = [checkpoint, early, lrp_reducer]
history = model.fit(
x_train, y_train,
batch_size=batch_size,
epochs=epochs,
steps_per_epoch=x_train.shape[0] // batch_size,
verbose=1,
callbacks=callbacks_list,
validation_data=(x_val, y_val),
validation_steps=x_val.shape[0]//batch_size
)
模型完成训练后,保存验证集中 MAE 误差最低的模型权重,对测试集进行评估:
python
train_result = model.evaluate(x=x_train, y=y_train, batch_size=batch_size)
valid_result = model.evaluate(x=x_val, y=y_val, batch_size=batch_size)
test_result = model.evaluate(x=x_test, y=y_test, batch_size=batch_size)
eval_result = pd.DataFrame(zip(train_result, valid_result, test_result), columns=['Train','Valid', 'Test'], index=['Loss','MAE'])
eval_result
6. 基于深度学习的面部关键点识别系统
利用 Flask + Bootstrap 框架搭建响应式布局的交互分析 web 系统,利用 keras load_model 加载训练好的性能最佳的模型,提供标准化 rest api,提供面部人脸关键点在线识别功能。
6.1 系统首页
6.2 人脸关键点在线识别
7. 结论
本项目利用 Tensorflow 和 Keras 构建卷积神经网络,利用扩充的数据集完成模型的训练、验证和测试,面部关键点识别像素级误差为0.95,小于1个像素点。并利用 Flask + Bootstrap 框架搭建交互式分析平台,通过上传待测试人脸图像,调用模型,完成关键点的识别和标绘。
B站视频详情及代码下载:基于深度学习的面部关键点识别系统_哔哩哔哩_bilibili
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。技术交流、源码获取 认准下方 CSDN 官方提供的学长 QQ 名片 :)
精彩专栏推荐订阅: