Opencv(python)实现Face_Detection

今天用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特征是用如下一些黑白矩形计算的特征


Opencv(python)实现Face_Detection_第1张图片
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)

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

Opencv(python)实现Face_Detection_第2张图片
Draw_fetures.jpg

你可能感兴趣的:(Opencv(python)实现Face_Detection)