基于深度学习的面部关键点识别系统

 温馨提示:文末有 CSDN 平台官方提供的师姐 QQ 名片 :) 

1. 项目简介

        面部关键点识别是指从图像中自动定位出人脸上的特定部位(如眼睛、鼻子、嘴巴等)的位置。随着计算机视觉技术的发展,面部关键点识别已经成为许多应用的核心技术之一,如面部识别、表情分析、虚拟试妆等。传统的基于特征的方法在光照变化、遮挡、姿态等方面表现不佳,而深度学习方法因其强大的特征表示能力和适应性,在这一领域取得了显著的进步。本项目利用 Tensorflow 和 Keras 构建卷积神经网络,利用扩充的数据集完成模型的训练、验证和测试,面部关键点识别像素级误差为0.95,小于1个像素点。并利用 Flask + Bootstrap 框架搭建交互式分析平台,通过上传待测试人脸图像,调用模型,完成关键点的识别和标绘。

基于深度学习的面部关键点识别系统

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条,样本过少,难以训练大规模参数的神经网络,针对人脸关键点数据,可以采用平移、旋转、像素增强等策略,进行样本的扩充:

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在计算机视觉领域取得了巨大的成功,尤其是在图像识别、目标检测和图像生成等方面。

        关键特点:

  1. 局部感受野:CNN通过卷积层捕捉输入数据的局部特征,每个神经元只与输入数据的一个局部区域相连接。
  2. 权重共享:在卷积层中,同一个卷积核的权重在整个输入数据上共享,这减少了模型参数的数量,提高了训练效率。
  3. 池化层:CNN通常在卷积层之后使用池化层来降低特征维度,减少计算量,同时保持特征的不变性。
  4. 层次结构:CNN通过多个卷积和池化层的堆叠,逐渐提取从低级到高级的特征

        Tensorflow是一个开源的机器学习框架,而Keras是一个高级API,它可以运行在Tensorflow之上,使得构建和训练神经网络变得更加简单。

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 最低的模型权重:

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 误差最低的模型权重,对测试集进行评估:

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 框架搭建交互式分析平台,通过上传待测试人脸图像,调用模型,完成关键点的识别和标绘。 

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。技术交流、源码获取认准下方 CSDN 官方提供的学长 QQ 名片 :)

精彩专栏推荐订阅:

1. Python数据挖掘精品实战案例

2. 计算机视觉 CV 精品实战案例

3. 自然语言处理 NLP 精品实战案例

### 构建面部识别系统的概述 构建一个面部识别系统涉及多个阶段和技术栈的选择。以下是关于如何构建面部识别系统以及可能使用的工具和框架的详细介绍。 #### 工具和框架选择 1. **开源工具** 可以考虑使用 FER(Facial Expression Recognition)作为基础工具之一,它支持通过图像或视频实时分析和识别面部表情,并提供多种分类选项,如愤怒、厌恶、恐惧等[^1]。然而需要注意的是,FER 主要专注于表情识别而非身份验证。 2. **人脸识别库 face_recognition** 对于更具体的人脸识别需求,可以采用 `face_recognition` 库。该库由 David Gohel 开发并维护,在 GitHub 上有详细的文档指导安装与使用方法[^2]。此库基于 dlib 和 OpenCV 实现,能够达到超过 99.38% 的高精度识别人脸的能力。 3. **深度学习框架** 如果希望进一步定制化模型或者提升性能,则可引入 TensorFlow 或 PyTorch 这样的主流深度学习框架来训练自己的 CNN 模型用于人脸检测与特征提取任务。这些框架提供了强大的灵活性和支持大规模数据集处理的功能。 #### 技术实现流程 - 数据收集:获取大量带标签的人脸图片作为训练素材。 - 预处理:包括裁剪、调整大小、灰度转换等一系列操作以便后续算法更好地运行。 - 特征提取:利用预训练好的模型比如 VGGFace, FaceNet 来抽取每张脸部照片中的关键属性向量表示形式。 - 训练模型:选用合适的损失函数配合优化器完成监督学习过程从而得到最终可用于预测的新模型版本号。 - 测试评估:最后一步是对整个系统进行全面测试确保其准确性满足实际应用场景下的预期目标值范围之内。 ```python import face_recognition from PIL import Image, ImageDraw # 加载一张已知人物的照片样本 known_image = face_recognition.load_image_file("person.jpg") encoding_of_known_person = face_recognition.face_encodings(known_image)[0] # 将未知面孔加载到程序当中去比较看看是不是同一个人物对象存在其中某处位置上 unknown_image = face_recognition.load_image_file("group_photo.png") encodings_in_unknown_picture = face_recognition.face_encodings(unknown_image) pil_image = Image.fromarray(unknown_image) draw = ImageDraw.Draw(pil_image) for (top,right,bottom,left), unknown_face_encoding in zip(face_recognition.face_locations(unknown_image), encodings_in_unknown_picture): matches = face_recognition.compare_faces([encoding_of_known_person], unknown_face_encoding) name = "Unknown" if True in matches: first_match_index = matches.index(True) name = "Person" draw.rectangle(((left,top),(right,bottom)), outline=(0,255,0)) text_width,text_height=draw.textsize(name) draw.rectangle(((left,bottom-text_height-10),(right,bottom)),fill=(0,255,0),outline=(0,255,0)) draw.text((left+6,bottom-text_height-5),name,fill=(255,255,255)) del draw pil_image.show() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python极客之家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值