【火炉炼AI】机器学习055-使用LBP直方图建立人脸识别器

【火炉炼AI】机器学习055-使用LBP直方图建立人脸识别器

(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

在我前面的博文【火炉炼AI】机器学习052-OpenCV构建人脸鼻子眼睛检测器中,讲到了人脸检测的方法和代码实现,但在很多实际场合,我们需要做的是人脸识别,即判断图片中的那张脸是张三还是李四,故而本篇文章我们来看看如何使用LBP直方图来建立一个人脸识别器。


1. 局部二值模式简介

局部二值模式(Local Binary Pattern, LBP)是一种用来描述图像局部纹理特征的算子,其最大优势在于旋转不变性,灰度不变性,能够多分辨分析。局部纹理分析有很多潜在的应用,比如工业表层检测,远程监控,图像分析等。

LBP的基本思想是:原始的LBP算子是3*3的窗口,以中心像素为阈值,将相邻的8个像素的灰度值与中心像素进行比较,如果大于,则设为1,小于则为0,故而得到这9个像素的二值化图,故而名称为局部二值化,如下图所示。从二值化图的左边中心点像素为起点,逆时针方向为正方形,按顺序取该二值化数值,便得到图中Pattern的二进制数值,此数值就是一个LBP编码,此时,我们称该中心像素点的LBP值为11110001。如果对一幅图像中的所有像素点都计算LBP值,得到的就是这幅图的LBP特征图。

关于灰度不变性:很明显,原始的局部图中如果灰度值都同时增加一个值或同时减去一个值,便相当于亮度增加或减少,但此时,得到的LBP编码不变,故而称为灰度不变性。需要注意的是:该灰度不变性仅仅适用于灰度值的单调变化。如下图

上面的LBP算子有一个缺陷,它只覆盖一个固定半径范围内的小区域,这显然不能满足不同尺寸和频率纹理的需要,故而有人对其进行改进,将3*3领域扩展到任意领域,并用圆形领域代替正方形领域,如下图为以中心像素点为圆心,R为半径,在圆上均匀的选取P个点作为采样点的情况。

上图中,R的大小决定了圆的大小,反映了二维空间的尺度;而P的大小决定了采样点数,反映了角度空间的分辨率。同样的,我们还可以改变R和P的值,实现不同的尺度和角度分辨率(如下图)。这也是以后“多分辨率分析”的理论基础。

上面的LBP算子虽然能够实现多分辨率,但却不是旋转不变性,图像的旋转会得到不同的LBP值,故有人提出了具有旋转不变性的LBP算子,即不断旋转圆形领域得到一系列初始定义的LBP值,取其最小值作为该领域的LBP值。

在LBP的应用中,比如人脸识别,纹理分析中,我们一般不将LBP图谱作为特征向量用于分类识别,而是采用LBP特征图的统计直方图来作为特征向量。

使用LBP直方图来进行特征提取的步骤一般为:

1) 首先将检测窗口划分为16×16的小区域(cell)

2) 对于每个cell中的一个像素,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值

3) 然后计算每个cell的直方图,即每个数字(假定是十进制数LBP值)出现的频率;然后对该直方图进行归一化处理

4)最后将得到的每个cell的统计直方图进行连接成为一个特征向量,也就是整幅图的LBP纹理特征向量;然后便可利用SVM或者其他机器学习算法进行分类了。

关于LBP的深入理论,可以参考博文:LBP(局部二值模式)特征提取原理局部二值模式(Local Binary Patterns)进行纹理分类


2. 准备数据集

本项目所用的数据集是脸部数据集的一个子集,此处我只选择三个人的脸部图片来进行测试。数据集有两部分,一个train的文件夹中有三个子文件夹,每个子文件夹代表一个人的脸部图片,test的文件夹只含有各种人脸图片,没有子文件夹。所以首先我们需要将这些图片加载到内存中,下面定义一个函数来加载图片。

# 定义一个函数来加载图片数据集
def load_train_set(imgs_folder,face_cascade):
    '''
    从imgs_folder中加载图片数据和标记,注意imgs_folder中包含有多个子文件夹,每个子文件夹的名称就是label
    '''
    folders=glob(os.path.join(imgs_folder,'*'))
    imgs_paths=[]
    [imgs_paths.extend(glob(os.path.join(folder, '*.*'))) for folder in folders]
    
    face_imgs=[]
    labels=[]
    # 对每一张图片都检测画面上的人脸
    for img_path in imgs_paths:
        image = cv2.imread(img_path, 0) 
        label=os.path.split(img_path)[0]
        img_folder=os.path.split(img_path)[0]
        faces = face_cascade.detectMultiScale(image, 1.1, 2, minSize=(100,100))
        for (x, y, w, h) in faces:
            face_imgs.append(image[y:y+h, x:x+w])
            
            labels.append(os.path.split(img_folder)[1])
            # 此处有点不合理,本数据集中每张图片只有一个人脸,故而可以用这个方式,
            # 如果有多个不同人的脸,则不能用折冲方式。
    # 将labels转换为数字
    label_encoder=LabelEncoder()
    encode_labels=label_encoder.fit_transform(labels)
    return face_imgs, encode_labels, label_encoder,labels

测试下上面的函数是否正常,且显示下加载的脸部照片

# 测试上面函数是否正常
face_cascade=cv2.CascadeClassifier('E:\PyProjects\DataSet\FireAI\cascade_files/haarcascade_frontalface_alt.xml')
face_imgs, labels, label_encoder,labels=load_train_set('E:\PyProjects\/DataSet\FireAI\/faces_dataset/train',face_cascade)
print(len(face_imgs)) # 有53张脸,但是检测得到56个结果,显然有几张图片中检测了多张脸
# 显示任一张人脸
# 由于cv2读取的是BGR,而plt是RGB,故而需要转化一下
plt.imshow(face_imgs[3],cmap='gray')

从打印的结果可以看出,多了三张图片,说明有三张不是脸部照片的图片混入,故而需要找出来删除。定义一个函数来找出错误图片

def find_false_faces(face_imgs):
    '''
    将所有脸部照片显示出来,如果发现有错误的,按d键,记录下错误的脸部照片
    '''
    need_del_ids=[]
    for idx,face in enumerate(face_imgs):
        cv2.namedWindow('check', cv2.WINDOW_NORMAL)
        cv2.resizeWindow('check', 500, 500)
        cv2.imshow('check', face)
        key = cv2.waitKey(0)

        if key==27: # 如果输入时Esc,则退出循环
            print('esc to exit')
            break
        elif key==100: # 如果输入d键,则记录该脸对应的id
            need_del_ids.append(idx)
    cv2.destroyAllWindows()
    print('finished...')
    return need_del_ids

故而需要从原始数据集中删除这三张图片以及对应的label信息

# 从数据集中删除这三张照片对应的信息
face_imgs=np.delete(np.array(face_imgs), need_del_ids, axis=0)
encode_labels=np.delete(np.array(encode_labels), need_del_ids, axis=0)
labels=np.delete(np.array(labels), need_del_ids,axis=0)
print(face_imgs.shape) # 53张图没错,元素已经变成了np.ndarray,故而只有行

3. 构建LBP直方图识别器

此处的LBP直方图识别器相当于一个分类模型,cv2已经帮我们封装好了这个分类模型,我们只需要调用即可。

# 构建createLBPHFaceRecognizer分类模型
from cv2.face import LBPHFaceRecognizer_create
recognizer=LBPHFaceRecognizer_create()
recognizer.train(face_imgs, encode_labels) # 模型训练

一旦人脸识别器模型训练好之后,就可以用来进行人脸识别了,下面看看识别新图片的人脸结果。

# 用训练好的模型预测新照片
def predict_imgs(new_imgs_folder, face_cascade,recognizer,label_encoder):
    '''
    用训练好的人脸识别器来识别人脸'''
    img_paths=glob(new_imgs_folder+'/*.*')
    predicted_imgs=[]
    for img_path in img_paths:
        image=cv2.imread(img_path)
        gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        faces=face_cascade.detectMultiScale(gray,1.1, 2, minSize=(100,100))
        for (x, y, w, h) in faces:
            cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3)
            predicted_index, conf = recognizer.predict(gray[y:y+h, x:x+w])
            predicted_label=label_encoder.inverse_transform([predicted_index])[0]
            cv2.putText(image, predicted_label,(x,y-20), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,255), 3)
        predicted_imgs.append(image)
    return predicted_imgs

得到的结果分别为:

当然,这个识别器只能识别训练图片中已经有的人脸,对于训练集中没有的人脸,它会预测不准确。比如,拿凤姐的图片来预测一下试试。

估计凤姐这张照片和Person3长的比较像,所以本模型将其预测为Person3

########################小**********结###############################

1,LBP直方图模型可以快速训练并快速识别,在人脸识别领域中有着比较广泛的应用。

#################################################################


注:本部分代码已经全部上传到(我的github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Matlab直方图Histogram的人脸识别程序-Processed histogram based Face Recognition.part3.rar 基于Matlab 直方图Histogram的人脸识别程序 因为数据库图片太大,所以分成几个压缩文件。 Face recognition 原理介绍: matlab12.jpg Recognizing objects from large image databases, histogram based methods have proved simplicity and usefulness in last decade. Initially, this idea was based on color histograms that were launched by swain [1]. This algorithm presents the first part of our proposed technique named as “Histogram processed Face Recognition” [2] For training, grayscale images with 256 gray levels are used. Firstly, frequency of every gray-level is computed and stored in vectors for further processing. Secondly, mean of consecutive nine frequencies from the stored vectors is calculated and are stored in another vectors for later use in testing phase. This mean vector is used for calculating the absolute differences among the mean of trained images and the test image. Finally the minimum difference found identifies the matched class with test image. Recognition accuracy is of 99.75% [1] M. J. Swain and D. H. Ballard, “Indexing via color histogram”, In Proceedings of third international conference on Computer Vision , pages 390–393, Osaka, Japan, 1990. [2] Fazl-e-Basit, Younus Javed and Usman Qayyum, "Face Recognition using processed histogram and phase only correlation ", 3rd IEEE International Conference on Emerging Technology pp. 238-242

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值