【Tool】Dlib 人脸特征提取

2018-12-26  本文已影响0人  ItchyHiker

前面一篇文章讲了Dlib的人脸关键点提取: https://www.jianshu.com/p/5a49c157fd88
提取的关键点可以用于各种任务。
此外Dlib 提供了一个face embedding功能,简单来说就是将人脸编码为128维向量,这个向量可以用来分类,聚类,相似度计算等等。Python 包 face_recognition提供了Dlib C++特征提取的Python封装,这里我们使用这个接口来进行特征提取,然后进行几个简单的分类任务试验,一个是性别分类,一个是微笑表情分类。

数据集介绍

这里我们使用的数据集是CelebA, CelebA是一个人脸属性分类数据集,包含来自于10k个名人的200k图像,每张图片有40个脸部属性,5个角点信息,包含配准和没有配准的的数据。
https://www.cv-foundation.org/openaccess/content_iccv_2015/papers/Liu_Deep_Learning_Face_ICCV_2015_paper.pdf

image.png

数据准备

Dlib人脸特征提取

先安装python face_recognition 模块:

pip3 install face_recognition

使用方法,调用face_recognition 的 face_encodings 模块:

face_embedding = fr.face_encodings(img)

face_embedding里面包含了img中人脸的编码,如果检测到多个人脸的话会包含多个人脸编码特征。
Dlib 的这个模型是在LFW数据集上训练的,也可以用来进行人脸识别等,人脸比对等。

有了特征还需要对应的分类,list_attr_celeba.csv 中包含了celeba数据集中的各个属性的label,这里我们只使用Male和Smiling两个属性。
一个可以参考的数据准备脚本:

import os
import timeit
import cv2
from skimage import io as io
import face_recognition as fr
import numpy as np
import pickle
from tqdm import tqdm
from sklearn import datasets, svm, metrics
import pandas as pd
data_path = "/home/ubuntu/ihandy_seg/data/img_align_celeba" 
table = pd.read_csv("/home/ubuntu/ihandy_seg/data/list_attr_celeba.csv")
print(table.columns.values)
img_label = table.set_index('image_id').to_dict()["Smiling"]
def main():
    count = 0
    gender_data = list()
    img_files = [f for f in os.listdir(data_path) if not f.startswith('.')]
    for img_file in tqdm(img_files[0:5000]):
        try:
            # print('Processing {}'.format(img_file))
            print(os.path.join(data_path, img_file))
            img = io.imread(os.path.join(data_path, img_file))
            face_embedding = fr.face_encodings(img)
            if len(face_embedding) != 1:
                print("Failed")
                continue
            single_data = list()
            single_data.append(face_embedding[0])
            single_data.append(img_label[img_file])
            gender_data.append(single_data)
        except Exception as e:
            print(e)
            continue
    print('Saving as a pkl file')
    with open('celeba_smiling_data.pkl','wb') as f:
        pickle.dump(gender_data, f)
    print('Finished')

if __name__ == '__main__':
    main()

分类器训练

这里我们使用sklearn 的 SVM作为分类器,使用face embedding也就是提取的128维人脸特征作为分类器的输入,使用sklearn 的 GridSearch进行超参数搜索, 一共4865张图片,使用4000张作为训练数据,865张作为测试数据。

param_grid = {'C': [1e1, 1e2],
              'gamma': [10, 100], 
              'decision_function_shape':["ovo"],
                "degree":[3,4]}
classifier = GridSearchCV(svm.SVC(kernel='rbf', class_weight='balanced', verbose=True),
                   param_grid, cv=5)
classifier.fit(embedding_list_train, gender_label_list_train)

expected = gender_label_list_test
predicted = classifier.predict(embedding_list_test)

print("Classification report for classifier %s:\n%s\n"
      % (classifier, metrics.classification_report(expected, predicted)))
print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted))

分类结果:

针对性别分类测试取得了99%的准确度,而针对微笑/不微笑的分类测试只有68%准确度。

性别:

              precision    recall  f1-score   support

          -1       0.98      1.00      0.99       512
           1       0.99      0.98      0.99       353

   micro avg       0.99      0.99      0.99       865
   macro avg       0.99      0.99      0.99       865
weighted avg       0.99      0.99      0.99       865
Confusion matrix:
[[510   2]
 [  8 345]]

1: Male, -1: Female

Screen Shot 2018-12-26 at 5.26.51 PM.png Screen Shot 2018-12-26 at 5.26.57 PM.png

微笑:

              precision    recall  f1-score   support

          -1       0.68      0.73      0.70       446
           1       0.69      0.63      0.66       419

   micro avg       0.68      0.68      0.68       865
   macro avg       0.68      0.68      0.68       865
weighted avg       0.68      0.68      0.68       865
Confusion matrix:
[[326 120]
 [155 264]]

所有代码在这里:
https://github.com/ItchyHiker/Face_Attributes_Classification_with_Dlib

上一篇下一篇

猜你喜欢

热点阅读