> ## Content Index
> Fetch the complete content index at: https://yinguobing.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# 基于Heat Map的人脸特征点检测
- URL: https://yinguobing.com/blog/heat-map-based-facial-landmark-localization/
- Published: 2018-02-06T09:06:06.000Z
- Updated: 2018-02-08T01:43:46.000Z
- Description: 基于Heat Map的人脸特征点检测，在视频流中也许会有更加稳定的检测效果。
- Author: 尹国冰
- Tags: 深度学习, TensorFlow

之前的人脸特征点检测[系列文章](https://yinguobing.com/blog/deeplearning/)采用了一个深度卷积神经网络来实现特征点坐标的提取。本篇文章将介绍另外一种基于Heat Map的特征点检测方法。该方法的思路与之前有一些差异，猜测该方法有可能会输出更加稳定的结果。

## 检测坐标的稳定性

之前的网络模型的输入为一张128×128的图像，输出为一个代表68个坐标点的x与y坐标、长度为136的向量。经初步测试，该模型在复杂情况下的表现要优于Dlib的表现，如下图所示：

![与dlib的比较](https://yinguobing.com/blog/content/images/2017/12/cmp-411.gif)

但是该方案与之前提到的OpenFace[\[1\]](#fn1)相比还有很大的差距，尤其是在坐标点的稳定程度上。经过实际测试，当待检测人脸在视频中静止不动时，由于每一帧画面之间存在微小的变化，最终输出的坐标会发生小幅度跳动。当人脸区域大小128×128像素时，跳动的范围大致在1\~2个像素。

相比之下OpenFace的结果则相当的稳定。OpenFace并不是基于深度神经网络的方法，其技术方案中采用了多个被称为Local Neural Field的模型，负责对特征点可能存在的局部区域进行进一步的精细化检测，并输出Landmark Response Maps。具体如下图所示：

![lnf](https://yinguobing.com/blog/content/images/2018/02/lnf.jpeg)

而我当前采用的深度神经网络模型的来源是Face++发表的论文，且只采用了其中的前半段——论文中“由粗到细”检测策略中的粗检部分。鉴于两篇论文都采用了分阶段的检测策略，我怀疑坐标点抖动的原因是我并没有完整的实现论文所述的整个检测链条。

于是我尝试将Face++模型中的第二部分进行了实现[\[2\]](#fn2)，为了快速验证我只用第二部分模型对左眼外侧眼角的坐标位置进行了优化。经过实际测试，加入第二阶段的精检模型之后，最终的结果优于不加精检模型。如下图所示，其中粗检点用白色标记，精检之后的点采用绿色标记。可以明显的看到绿色点的位置更加贴近人物的外侧眼角。

![stage2-sample](https://yinguobing.com/blog/content/images/2018/02/stage2-sample.jpeg)

令人遗憾的是，加入精检模型之后并没有有效的改善坐标点的稳定性，我个人甚至感觉模型变得更加的敏感，坐标抖动更加的严重。至于原因我有多个猜测，有可能是模型过拟合；也有可能更精确某种程度上就意味着更敏感。

总之，直接输出坐标点绝对数值的方案有可能是不合适的。

## 用于人骨骼关节点检测的OpenPose

机缘巧合，看到了一篇CVPR上发表的关于人骨骼关节点检测的论文[\[3\]](#fn3)。该论文采用深度神经网络实现了图像中人骨骼关节点位置的提取，作者在Github上释出了源代码[\[4\]](#fn4)。经过实际测试，该方法获得的检测结果非常稳定。考虑到关节这种人类都很难做到前后一致标记的物体，该论文实现的效果让我略感惊喜。

![图片来自OpenPose作者](https://yinguobing.com/blog/content/images/2018/02/openpose-shake.gif)

作者在论文里对OpenPose的架构做了详细的介绍。与之前我所采用的网络架构相比这是一个非常复杂的网络。结构如下图所示，总体上可以分为两大部分：VGG19为特征提取部分；提取之后的特征被送入后半部分——一个多级神经网络。后半部分的每一级包含两个分支，分支1负责从图片中检测人体的关节点位置，分支2则需要计算Part Affinity Fields，用来将检测到的特征点进行区分与组合，形成若干完整的人体。

![open-pose--arch](https://yinguobing.com/blog/content/images/2018/02/open-pose--arch.jpeg)

其中分支1正是我想要的，因为在我当前的方案中人脸关键点的检测是局限在一个人脸框中的，所以不需要分支2来将它们组合起来。再仔细看分支1，它的输出并非常规所想象的所有关节点的坐标数值，而是一张反映了关节点可能存在的位置概率分布图，即下图中右侧的Heatmap。

![图片来自OpenPose作者](https://yinguobing.com/blog/content/images/2018/02/openpose-inference_result.jpeg)

OpenFace与OpenPose对于位置的预测均是以输出概率分布图为目标，这是否是某种巧合？

## 实例级物体检测Mask R-CNN

鉴于深度卷积神经网络拥有强大的特征提取能力，将其嵌入在物体检测框架中的尝试层出不穷。其中较为出名的有R-CNN，以及后续的Fast R-CNN， Faster R-CNN和Mask R-CNN。论文与相关资料可以在作者Ross Girshick的个人主页可以下载到[\[5\]](#fn5)。在2017年CVPR的一个物体检测WORKSHOP上，Ross做了一段与R-CNN相关的分享[\[6\]](#fn6)。在分享资料中有这么一张幻灯片。

![faster-rcnn](https://yinguobing.com/blog/content/images/2018/02/faster-rcnn.jpeg)

Mask R-CNN可以输出人体骨骼关节点的位置，体现在最终的输出端大小：28×28×17，即17张骨骼关键点的概率分布图，如上图右侧所示。颜色越热，概率越大。

综合考虑以上情况，也许，输出一张特征点的位置的概率分布图是一个不错的思路？

如果真是如此，那么至少应当尝试一下。

---

1. [https://github.com/TadasBaltrusaitis/OpenFace](https://github.com/TadasBaltrusaitis/OpenFace?ref=yinguobing.com) [↩︎](#fnref1)
2. [https://github.com/yinguobing/cnn-facial-landmark/tree/stage2](https://github.com/yinguobing/cnn-facial-landmark/tree/stage2?ref=yinguobing.com) [↩︎](#fnref2)
3. [Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields, Cao, Z., etc, CVPR 2017](https://arxiv.org/abs/1611.08050?ref=yinguobing.com) [↩︎](#fnref3)
4. [https://github.com/ZheC/Realtime\_Multi-Person\_Pose\_Estimation](https://github.com/ZheC/Realtime%5FMulti-Person%5FPose%5FEstimation?ref=yinguobing.com) [↩︎](#fnref4)
5. [http://www.rossgirshick.info/](http://www.rossgirshick.info/?ref=yinguobing.com) [↩︎](#fnref5)
6. [http://deeplearning.csail.mit.edu/instance\_ross.pdf](http://deeplearning.csail.mit.edu/instance%5Fross.pdf?ref=yinguobing.com) [↩︎](#fnref6)