1. FaceDetection
    1. 算法架构
      1. 顶层:多个针对不同姿态的快速LAB特征分类器
        1. LAB特征
          1. LAB特征是那些结合8个局部邻接2-矩形的二分Haar特征,它们大小相同并且共享同一个中心矩形
          2. LAB特征示例
        2. 级联强分类器
          1. 将若干个强分类器由简单到复杂排列,希望经过训练使每个强分类器都有较高检测率,而误识率可以放低,比如几乎99%的人脸可以通过,但50%的非人脸也可以通过,
          2. 是一种退化的决策树,决策树是二叉树,级联是对于前面不匹配的直接抛弃,不会继续分类
        3. 如何搜索人脸
          1. 在图像中做“穷尽搜索”,扫描所有的分类器,这些分类器会在图像上搜索所有可能的位置和大小
          2. 示例
          3. 搜索方法
          4. 窗口中心分类器
          5. 存在重复计算
          6. 图中矩形框内的特征,被每个特征分类器计算。
          7. 副产品是计算过程会得到特征图
          8. 滑动窗口以计算图中所有位置的所有特征
          9. 特征中心分类器
          10. 计算方法
          11. 特征值图像可以通过扫描图像中所有坐标的upper特征来计算
          12. 然后特征中心的分类器会运行在特征值图像中,并不再需要特征计算操作
          13. 注意
          14. 所有的特征都是相同大小,因为他们都是通过在图像平移了一个特殊特征来搜集的。
          15. 当然,任意大小窗口都可以用来构建特征中心分类器。但是最好是选择最有效率的一个
          16. 贪心算法
          17. 两种算法的计算差异
          18. 假若分类窗口尺寸为24x24,特征为3x3的LAB特征,因此一个窗口中会有256((24-9+1)x(24-9+1))个特征
          19. 窗口中心方法
          20. 所有的256个分类操作将导致这256个特征在每个候选窗口中被操作一次,所以,每个窗口的平均分类操作数是256
          21. 特征中心级联方法
          22. 随着过程的推进某些窗口会被抛弃,每个窗口的平均分类操作是小于256的
          23. 使用 RealBoost学习算法来学习线性(窗口中心或特征中心)分类函数
      2. 中层:若干基于SURF特征的多层感知机
        1. LAB级联阶段之后,大部分非人脸窗口被抛弃,剩下的部分对于单个LAB 特征难以处理。因此,接下来,候选窗口将交给更复杂的分类器来处理,比如带 SURF的MLP
        2. 粗粒度MLP
          1. 输入是候选窗口的SURF特征
          2. MLP级联可以连接多个LAB级联分类器
      3. 底层:一个统一的基于SURF特征的多层感知机,来处理所有姿态的候选窗口
        1. 多视角人脸外貌之间存在一些冲突,主要源于非对齐特征
          1. 基于坐标抽取的特征存在语义不一致问题
          2. 采取了一种基于形状索引的方法在语义相同的位置上抽取特征作为细粒度MLP级联分类器的输入
    2. 使用步骤
      1. 1. 载入头文件
        1. #include "opencv2/highgui/highgui.hpp"
        2. #include "opencv2/imgproc/imgproc.hpp"
        3. #include "face_detection.h"
      2. 2 加载人脸识别引擎
        1. seeta::FaceDetection detector(‘seeta_fd_frontal_v1.0’);
      3. 3. 设置最小人脸大小
        1. 这个根据实际情况调整,图片中,人脸越大,这个值也越大,因为这个值越小,人脸识别速度越慢。
        2. detector.SetMinFaceSize(40);
      4. 4. 识别图片中的人脸
        1. std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
      5. 5. 输出人脸识别的结果
        1. 人脸左上角坐标
        2. 人脸长和宽
        3. faces[i].bbox.x
        4. faces[i].bbox.y
        5. faces[i].bbox.width
        6. faces[i].bbox.height
    3. 代码结构
      1. face_detection.cpp
      2. fust.cpp
        1. LoadModel 从模型路径载入模型
        2. Detect
        3. CreateModelReader根据传入的分类类别创建不同的reader
          1. LAB_Boosted_Classifier
          2. LABBoostModelReader
          3. SURF_MLP
          4. SURFMLPModelReader
        4. CreateClassifier 根据传入的分类类别创建不同的分类器
          1. LAB_Boosted_Classifier
          2. LABBoostedClassifier
          3. SURF_MLP
          4. SURFMLP
        5. CreateFeatureMap 根据传入的分类类别创建不同FeatureMap
          1. LAB_Boosted_Classifier
          2. LABFeatureMap
          3. SURF_MLP
          4. SURFFeatureMap
        6. GetWindowData 从输入的图像中获取指定矩形的窗口ROI数据
      3. image_pyramid.cpp 将图像按照一定比例同时缩放宽和高
        1. GetNextScaleImage 根据传入的缩放尺寸缩放图像
        2. SetImage1x 重置图像的缓存空间大小
        3. UpdateBufScaled()
      4. lab_boost_model_reader.cpp
        1. Read
        2. ReadFeatureParam
        3. ReadBaseClassifierParam
      5. surf_mlp_model_reader.cpp
        1. Read
      6. lab_boosted_classifier.cpp
        1. SetWeights
        2. Classify
        3. AddFeature
        4. AddBaseClassifier
      7. lab_feature_map.cpp
        1. Compute
        2. GetStdDev
        3. Reshape
        4. ComputeIntegralImages 计算积分图像
        5. ComputeRectSum
        6. ComputeFeatureMap 计算LAB特征
      8. mlp.cpp
        1. MLPLayer::Compute
        2. MLP::Compute
        3. MLP::AddLayer
      9. nms.cpp
        1. CompareBBox
        2. NonMaximumSuppression
      10. surf_feature_map.cpp
        1. SURFFeaturePool
          1. AddPatchFormat
          2. Create()
          3. AddAllFeaturesToPool
        2. SURFFeatureMap
          1. :Compute
          2. GetFeatureVector
          3. InitFeaturePool
          4. Reshape
          5. ComputeGradientImages
          6. ComputeGradX
          7. ComputeGradY
          8. ComputeIntegralImages
          9. MaskIntegralChannel
          10. Integral
          11. VectorCumAdd
          12. ComputeFeatureVector
          13. NormalizeFeatureVectorL2
      11. surf_mlp.cpp
        1. Classify
        2. AddFeatureByID
        3. AddLayer
  2. FaceAlignment
    1. 核心
      1. 级联多个栈式自编码器来回归5个特征点(两个眼睛,鼻子,两个嘴角)
      2. CFAN由4个级连的SAN网络构成, 每个都是四层网络,三个隐层, 用sigmoid激活,最后一层为线性激活
        1. 第一个全局SAN用于粗定位68个形状特征点
        2. 输入为 50x50 的低分辨率图像,即2500个输入单元
        3. 中间层分别为1600,900,400个单元
        4. 输出为68个形状特征点的位置,即 68x2=136个输出元素
        5. 三个局部SAN
        6. 输入为68个特征点在高分辨率图中从周围区域提取出来的形状索引特征(SIFT)。
        7. 原始输入应该是从每个形状特征点周围提取了128个SIFT特征,即共 68x128=8704个特征。
        8. 采用PCA的方法,分别降维到了1695、2418、2440输入元素
        9. 中间层分别为1296,784,400个单元
        10. 输出仍然为逐步校正后的136个特征位置
      3. 提出一种由粗到细的自编码网络(CFAN)来求解从人脸表现到人脸形状的复杂的非线性映射过程
    2. 算法步骤
      1. 1.直接从人脸的低分辨率中快速估计大致的人脸形状S0
      2. 2 提高输入人脸的分辨率,并抽取当前人脸形状S0(相应地提升分辨率)各特征点位置的局部特征
      3. 3 输入到下一级自编码网络进一步优化对齐结果
  3. FaceIdentification
    1. 核心
      1. 采用一个9层CNN(VIPFaceNet)来提取人脸特征
      2. VIPFaceNet由7层CNN+2层全连接组成,修改自AlexNet
    2. 优化
      1. 将5x5的卷积核拆分为2层3x3卷积核,增加了网络深度,而没有增加计算量
      2. 减少了每个卷积层的kernel数目,以及最后一层全连接层神经元数目
      3. 引入Fast Normalization Layer加速网络收敛速度,并提升模型泛化能力