文章目录
一、实验目的
- 利用所提供的人脸微笑数据集(genki4k),训练一个微笑/非微笑识别模型,完成对人脸图片的微笑与非的识别,输出训练(train)和测试(test)的精度值(F1-score和ROC);
- 然后保存这个模型,将其应用到人脸实时采集视频的微笑检测中,当检测到微笑人脸,视频窗口输出“smile”,否则输出“non smile”;List item
- 当识别结果准确时,按“s”键,保存10张对应分类的图片到本地目录。人脸表情特征的选择不限,可以是HoG、SIFT、dlib(68个关键点), 训练算法采用SVM(sklearn或libsvm)。
二、HOG特征值提取
HOG特征提取流程可分为5个部分:检测窗口、归一化图像、计算梯度、统计直方图、梯度直方图归一化、得到HOG特征向量
-
检测窗口
HOG通过窗口(window)和块(block)将图像进行分割。通过以细胞(cell)为单位,对图像某一区域的像素值进行数学计算处理。 -
归一化图像
归一化分为gamma空间和颜色空间归一化。归一化同时可以避免在图像的纹理强度中,局部的表层曝光贡献度的比重较大的情况。 -
计算梯度
计算图像横坐标和纵坐标方向的梯度,并根据横坐标和纵坐标的梯度,计算梯度方向。 -
构建梯度直方图
HOG构建方向梯度直方图在细胞(cell)中完成:bins(可理解为划分的个数)决定方向的划分。一般bins取9,将梯度方向划分为9个区间。例如,假设一个细胞尺寸为6*6,则对这个细胞内的36个像素点,先判断像素点梯度方向所属的区间,后根据像素点的梯度幅值大小和梯度方向的大小进行加权于对应的梯度方向区间。 -
块内进行细胞归一化梯度直方图
局部光照的变化及前景-背景对比度的变化,使梯度强度的变化范围很大,在此需要进行归一6化。 -
生成HOG特征向量
三、代码实现
genki4k数据集
1.导入包
# 导入包
import numpy as np
import cv2
import dlib
import random#构建随机测试集和训练集
from sklearn.svm import SVC #导入svm
from sklearn.svm import LinearSVC #导入线性svm
from sklearn.pipeline import Pipeline #导入python里的管道
import os
import joblib#保存模型
from sklearn.preprocessing import StandardScaler,PolynomialFeatures #导入多项式回归和标准化
import tqdm
2.图片路径
folder_path='D:/Face/genki4k/'
label='labels.txt'#标签文件
pic_folder='files/'#图片文件路径
3.获得默认的人脸检测器和训练好的人脸68特征点检测器
#获得默认的人脸检测器和训练好的人脸68特征点检测器
def get_detector_and_predicyor():
#使用dlib自带的frontal_face_detector作为我们的特征提取器
detector = dlib.get_frontal_face_detector()
"""
功能:人脸检测画框
参数:PythonFunction和in Classes
in classes表示采样次数,次数越多获取的人脸的次数越多,但更容易框错
返回值是矩形的坐标,每个矩形为一个人脸(默认的人脸检测器)
"""
#返回训练好的人脸68特征点检测器
predictor = dlib.shape_predictor('D:/Face/shape_predictor_68_face_landmarks.dat')
return detector,predictor
#获取检测器
detector,predictor=get_detector_and_predicyor()
4.截取面部
def cut_face(img,detector,predictor):
#截取面部
img_gry=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
rects = detector(img_gry, 0)
if len(rects)!=0:
mouth_x=0
mouth_y=0
landmarks = np.matrix([[p.x, p.y] for p in predictor(img,rects[0]).parts()])
for i in range(47,67):#嘴巴范围
mouth_x+=landmarks[i][0,0]
mouth_y+=landmarks[i][0,1]
mouth_x=int(mouth_x/20)
mouth_y=int(mouth_y/20)
#裁剪图片
img_cut=img_gry[mouth_y-20:mouth_y+20,mouth_x-20:mouth_x+20]
return img_cut
else:
return 0#检测不到人脸返回0
5.提取特征值
#提取特征值
def get_feature(files_train,face,face_feature):
for i in tqdm.tqdm(range(len(files_train))):
img=cv2.imread(folder_path+pic_folder+files_train[i])
cut_img=cut_face(img,detector,predictor)
if type(cut_img)!