基于开源模型搭建实时人脸识别系统(三):人脸关键点、对齐模型概览与模型选型

基于开源模型搭建实时人脸识别系统(二):人脸检测概览与模型选型_CodingInCV的博客-CSDN博客

摘要

人脸对齐(face alignment)或者人脸关键点(face alignment)是定位人脸上的关键点,是很多基于人脸的任务的前置步骤,比如人脸识别、表情分析、人脸变装(makeup)等。人脸对齐有2D和3D对齐,本篇主要讲2D对齐。

  • 人脸姿态对齐:人脸识别等算法都需要对人脸的姿态进行对齐从而提高模型的精度。
  • 人脸美颜与编辑:基于关键点可以精确分析脸型、眼睛形状、鼻子形状等,从而对人脸的特定位置进行修饰加工,实现人脸特效美颜,贴片等娱乐功能。
  • 人脸表情分析与嘴型识别:基于关键点可以对人的面部表情进行分析,从而用于互动娱乐,行为预测等场景。

    根据关键点个数,主要分为5点、68点、98点、106点等。



    人脸关键点定位的困难主要来源于以下几个方面:
  • 人脸姿态
  • 人脸遮挡
  • 人脸表情
  • 环境光照

人脸关键点算法概览

同样的人脸关键点算法也分为传统和深度学习时期,目前主要使用深度学习。

对于关键点任务,一般将其作为一个回归任务,即目标是回归每个关键点的位置;另一种方式是引入heatmap。这里不展开阐述,需要更深入了解,可以阅读下面的链接。

更多:
人脸关键点综述 - 知乎 (zhihu.com)
Article (iasj.net)

算法选型

Face Alignment | Papers With Code

人脸对齐开源的算法还挺多,但是这sota算法开源的权重都太大,无法达到我们的轻量化要求。人脸对齐作为人脸质量筛选和人脸识别前的步骤,不能计算量太大。

按照计算量要求,我们选择了这一算法(选择其中的Student@128):

人脸关键点模型的输入是人脸区域,具体而言是对人脸检测模型得到的人脸框进行一定的放大后的区域。

修改后模型的推理代码如下:

Python 复制代码
class FaceLandmarks(BaseModel):
    def __init__(self, model_path, device="cpu", **kwargs) -> None:
        super().__init__(model_path, device, **kwargs)
        self.input_size = 128
        self.extend = [0.2, 0.3]

    def preprocess(self, image: np.ndarray, bbox: np.ndarray):
        bbox_width = bbox[2] - bbox[0]
        bbox_height = bbox[3] - bbox[1]

        face_size = bbox_width
        # face_size = int(max(bbox_width, bbox_height))
        face_width = (1 + 2 * self.extend[0]) * face_size
        center = [(bbox[0] + bbox[2]) // 2, (bbox[1] + bbox[3]) // 2]

        ### make the box as square
        crop_bbox = np.zeros(4, dtype=np.int32)
        crop_bbox[0] = center[0] - face_width // 2
        crop_bbox[1] = center[1] - face_width // 2
        crop_bbox[2] = center[0] + face_width // 2
        crop_bbox[3] = center[1] + face_width // 2

        # limit the box in the image
        crop_bbox[0] = max(0, crop_bbox[0])
        crop_bbox[1] = max(0, crop_bbox[1])
        crop_bbox[2] = min(image.shape[1], crop_bbox[2])
        crop_bbox[3] = min(image.shape[0], crop_bbox[3])
        
        # crop
        crop_bbox = crop_bbox.astype(np.int32)
        crop_image = image[crop_bbox[1] : crop_bbox[3], crop_bbox[0] : crop_bbox[2], :]
        crop_image = cv2.resize(crop_image, (self.input_size, self.input_size))

        return crop_image, crop_bbox

    def run(self, image: np.ndarray, bbox: np.ndarray) -> np.ndarray:
        input, crop_box = self.preprocess(image, bbox)
        input = input.astype(np.float32)
        input = input / 255.0
        input = input.transpose((2, 0, 1))
        input = np.expand_dims(input, axis=0)
        output, _ = self.inference(input)
        landmarks = np.array(output)[:98*2].reshape(-1, 2)
        landmarks = self.postprocess(landmarks, crop_box)

        #change 98 points to 5 points
        landmarks = landmarks[[96, 97, 54, 88, 92], :]
        return landmarks

    def postprocess(self, landmarks: np.ndarray, crop_box)->np.ndarray:
        h = crop_box[3] - crop_box[1]
        w = crop_box[2] - crop_box[0]

        landmarks[:, 0] = landmarks[:, 0] * w + crop_box[0]
        landmarks[:, 1] = landmarks[:, 1] * h + crop_box[1]
        return landmarks

测试

得到的关键点如下(为了方便后续的使用,我们将98关键点转换为了5个关键点):

CPU上的平均耗时为8ms, 还是非常快的。

结语

本篇简单介绍了人脸对齐,但只是从实用的角度浅尝辄止,感兴趣的还是需要搜索相关文献进一步学习。

源码欢迎光临我的面包多:CoderInCV的个人主页 (mbd.pub)

相关推荐
某公司摸鱼前端1 个月前
uniapp生物识别示例(人脸识别、指纹识别)
uni-app·人脸识别·指纹识别
—你的鼬先生1 个月前
从零开始使用树莓派debian系统使用opencv4.10.0进行人脸识别(保姆级教程)
python·opencv·debian·人脸识别·二维码识别·opencv安装
Jiaberrr2 个月前
教你如何在微信小程序中轻松实现人脸识别功能
javascript·微信小程序·小程序·人脸识别·百度ai
Nicolas8932 个月前
【隐私计算篇】利用多方安全计算MPC实现VGG16人脸识别隐私计算模型
人脸识别·分布式存储·隐私计算·mpc·vgg16·多方安全计算·明密文混合
Crazy Struggle2 个月前
.NET 开源的功能强大的人脸识别 API
人脸识别·.net·facerecognitiondotnet
从懒虫到爬虫2 个月前
基于PCA-SVM的人脸识别系统(MATLAB GUI)
机器学习·支持向量机·matlab·人脸识别
mcusun20003 个月前
ESP32人脸识别开发--人脸识别模型(六)
人脸识别·esp32
as_jopo3 个月前
windows中使用人脸识别库face_recognition的教程
windows·python·人脸识别
微学AI4 个月前
人工智能算法工程师(高级)课程1-单类目标识别之人脸检测识别技术MTCNN模型介绍与代码详解
人工智能·算法·人脸识别·mtcnn
天天代码码天天4 个月前
百度人脸识别Windows C++离线sdk C#接入
人脸识别