美文网首页
Opencv(python)实现Face_Detection

Opencv(python)实现Face_Detection

作者: Birdy潇 | 来源:发表于2017-08-27 16:32 被阅读0次

    今天用Opencv库来实现简单的人脸检测。

    简单来说,人脸检测就是在一副图像中找到人脸,在某些情况下还有要用bounding box将其框出来。那么怎么找呢?
    这就需要机器学习的知识,需要构建一个人脸分类器,首先收集人脸样本,这些作为正样本,在收集不是人脸的样本作为负样本。然后提取样本的特征(特征提取是一个大学问,一会儿后面介绍)这些样本特征是一个高维向量,将这些特征和对应的标签送入分类器进行训练,这种学习方式是supervised learning。

    1. 特征提取
      好,那该如何提取一幅图像的特征呢?图像由像素组成,每一个像素点又是由RGB三通道的不同值组成,也就是X*Y*3的一个矩阵,为了处理方便将图像灰度化处理:

    Gray(x,y)=R*0.3+G *0.59+B*0.11

    这样就转化为灰度图像了,opencv库里有自带的函数可以直接调用。
    转化为灰度图像之后就可以计算特征了,这里使用的是Haar特征,其他的还有HOG特征等等。Haar-like特征是用如下一些黑白矩形计算的特征


    Haar特征.jpg

    黑色区域的像素和减去白色区域的像素和得到的就是特征值,不同的黑白矩形能表征不一样的图像特征,一般计算一幅图像的特征值计算量较大,采用积分图的方法,遍历一遍图像就可以计算所有特征值,也是一种动态规划算法,这里略去不细讲。

    1. 有了特征接下来就是训练分类器了,在人脸检测方面用的是级联强分类器。
    • 先用训练样本训练一个弱分类器,调整阈值达到较小的误判率,这样的分类器为最优弱分类器。
    • 重新改变样本分布的权重,加大那些误判样本的权重,再次训练得到第二个最优分类器。
    • 训练N次得到N个最优分类器,再将N个分类器组合成一个强分类器。强分类器也就是最优弱分类器的加权投票。
    • 只有一个强分类器还是不够,再用多个强分类器级联就构成了最终的人脸分类器。
    1. 进行人脸检测
      有了分类器就可以进行人脸检测了,对于被检测图像采用滑动窗口的检测方法,在子窗口中计算特征值,有分类器进行检测。由于图像人脸大小不一,所以需要对图像Scaling。
    附上代码(opencv库已经很完善了):
    #-*-coding:utf-8-*-
    import numpy as np
    import cv2
    import os
    
    #定义人脸检测函数
    def Face_Detect(gray):
        #将图像灰度化
        #gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
        #opencv有已经训练好的分类器可以直接加载使用
        #加载Haar级联分类器
        faces_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
        #滑动窗口检测,返回有人脸的区域坐标,1.3为窗口每次缩放的倍数,
        faces=faces_cascade.detectMultiScale(gray,1.3,5)
        result=[]
        for (x,y,width,height) in faces:
            result.append((x,y,x+width,y+height))
    
        return result
    
    #定义眼睛检测函数
    def Eye_Detect(gray):
        #gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
        eye_cascade=cv2.CascadeClassifier('haarcascade_eye.xml')
        eyes=eye_cascade.detectMultiScale(gray,1.3,5)
        result=[]
        for (x,y,width,height) in eyes:
            result.append((x,y,x+width,y+height))
    
        return result
    
    #检测并框出人脸和眼睛
    def Draw_features(img_name):
        #检测人脸和眼睛,在检测出人脸的区域内检测眼睛,防止眼睛检测在非人脸区域出现
        #读取图像并灰度化
        img=cv2.imread(img_name)
        gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        #检测人脸
        faces=Face_Detect(gray)
        #在原图上框出人脸
        if faces:
            for (x1,y1,x2,y2) in faces:
                cv2.rectangle(img,(x1,y1),(x2,y2),(255,255,0),thickness=8)
    
                face_region=gray[y1:y2,x1:x2]
                eyes=Eye_Detect(face_region)
                if eyes:
                    for (xa,ya,xb,yb) in eyes:
                        cv2.rectangle(img,(xa+x1,ya+y1),(xb+x1,yb+y1),(154,250,0),thickness=6)
    
        cv2.imwrite('C:\\Users\Administrator\Desktop\Draw_fetures.jpg',img)
    
    #Test
    if __name__=='__main__':
        filename='C:\\Users\Administrator\Documents\Tencent Files\\1246540310\FileRecv\MobileFile\me2.jpg'
        Draw_features(filename)
    

    眼睛的检测效果没有那么好,把我的嘴角和后面人的腿都检测出来了

    Draw_fetures.jpg

    相关文章

      网友评论

          本文标题:Opencv(python)实现Face_Detection

          本文链接:https://www.haomeiwen.com/subject/yygbdxtx.html