利用OpenCV检测人脸(python实现)

简介: 利用OpenCV检测人脸(python实现)

1. 前言


   前段时间自制了个人脸表情识别软件,许多步骤用到了OpenCV中的函数和功能,其中就包括人脸图像检测与定位。作为人脸表情识别的第一步需要在输入图像中找到人脸确切的位置,而OpenCV中的haar分类器可以简单方便地解决这一预处理问题。接下来详细介绍图片中人脸的检测和标记实现过程。


2. OpenCV haar分类器


   Haar-like特征最早是由Papageorgiou等人用于物体检测的数字图像特征,而Viola和Jones在此基础上,使用3种类型4种形式的特征。



   Haar特征分为三类:边缘特征、线性特征、中心特征和对角线特征,组合成特征模板。特征模板内有白色和黑色两种矩形,并定义该模板的特征值为白色矩形像素和减去黑色矩形像素和。Haar特征值反映了图像的灰度变化情况。例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述特定走向(水平、垂直、对角)的结构。

   这类矩形特征模板由两个或多个全等的黑白矩形相邻组合而成,而矩形特征值是白色矩形的灰度值的和减去黑色矩形的灰度值的和,矩形特征对一些简单的图形结构,如线段、边缘比较敏感。如果把这样的矩形放在一个非人脸区域,那么计算出的特征值应该和人脸特征值不一样,所以这些矩形就是为了把人脸特征量化,以区分人脸和非人脸。


   以Haar特征分类器为基础的对象检测技术是一种非常有效的对象检测技术,但其实并不新颖,不过因为技术成熟好用这里依然采用这一方法。它是基于机器学习的,使用大量的正负样本训练得到分类器。其实就是基于对人脸特征的描述,分类器根据训练的样品数据进行训练,完成后即可感知读取到的图片上的特征,进而对图片进行人脸识别。


   OpenCV已在GitHub训练结果网址上分享了其训练好的结果数据,分类器普适性较好可满足一般人脸检测的需要,调用的代码如下:

python
import cv2
face_cascade = cv2.CascadeClassifier(r'./haarcascade_frontalface_default.xml')


   通过以上代码可以得到一个训练好的人脸检测分类器,其中的xml文件可在GitHub训练结果网址上下载得到,下一步就是检测图片中的人脸,在OpenCV中调用的代码如下:

python
# 检测脸部
faces = face_cascade.detectMultiScale(gray, 
  scaleFactor=1.1, 
  minNeighbors=5, 
  minSize=(30, 30),
        flags=cv2.CASCADE_SCALE_IMAGE)
print('Detected ', len(faces), " face")
# 在图片中显示检测到的人脸数
label = 'Result: Detected ' + str(len(faces)) +" faces !"
cv2.putText(img, label, (10, 20),
           cv2.FONT_HERSHEY_SCRIPT_COMPLEX, 
           0.8, (0, 0, 0), 1)
# 显示图片
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()


   通过以上代码可以得到检测出的人脸数据,其中faces中包含了检测到的所有人脸区域的起始点位置及区域大小,可以通过遍历该变量获得每张人脸的检测具体数据并据此标记人脸位置。上面代码运行的几个如下图所示:



   以上代码中用到了putText函数,如下代码中各参数依次是:图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细

python
cv2.putText(img, label, (10, 20),
           cv2.FONT_HERSHEY_SCRIPT_COMPLEX, 
           0.8, (0, 0, 0), 1)

   


3. 人脸标记


   上一节中可知分类器的detectMultiScale方法可以得到检测出的人脸区域,这一节就可以据此对人脸进行标记,在此之前先读入一张图片并调整为灰度图,代码如下:

python
import cv2
face_cascade = cv2.CascadeClassifier('haarcascade_files/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_files/haarcascade_eye.xml')
img = cv2.imread('west.jpeg')# 读取图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转为灰度图
# 检测脸部
faces = face_cascade.detectMultiScale(gray,
                            scaleFactor=1.1,
                            minNeighbors=5,
                            minSize=(30, 30),
                            flags=cv2.CASCADE_SCALE_IMAGE)
print('Detected ', len(faces), " face")


   接下来对脸部区域进行标记,利用OpenCV中的rectanglecircle函数可以在图像中添加自定义的矩形、圆形标记,对检测结果区域进行标记的代码如下:

python
# 标记位置
for (x, y, w, h) in faces:
    img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 1)
    # cv2.circle(img, (int((x + x + w) / 2), int((y + y + h) / 2)), int(w / 2), (0, 255, 0), 1)
    roi_gray = gray[y: y + h, x: x + w]
    roi_color = img[y: y + h, x: x + w]
    eyes = eye_cascade.detectMultiScale(roi_gray)
    for (ex, ey, ew, eh) in eyes:
        cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 1)


   以上代码同时检测和标记了眼睛的位置,同样的使用的是OpenCV中得到的分类器,可以得到眼睛的位置并用长方形的颜色框标出来。代码通过遍历检测到的人脸数据,对每个人脸进行标记,并在每个人脸上检测眼睛的位置标识出来。通过如下代码显示图片:

python
label = 'Result: Detected ' + str(len(faces)) +" faces !"
cv2.putText(img, label, (10, 20),
            cv2.FONT_HERSHEY_SCRIPT_COMPLEX, 
            0.8, (0, 0, 0), 1)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()


运行结果如下图所示:



4. 完整代码


   要使用博文中的代码需先安装OpenCV库,可直接下载或通过在终端输入如下代码安装:

python
pip install opencv-python


为方便大家使用参考,在此贴出全部的完整代码(需自行准备图片):

python
# encoding:utf-8
import cv2
import numpy as np
# 运行之前,检查cascade文件路径是否在相应的目录下
face_cascade = cv2.CascadeClassifier('haarcascade_files/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_files/haarcascade_eye.xml')
# 读取图像
img = cv2.imread('lovers.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转为灰度图
# 检测脸部
faces = face_cascade.detectMultiScale(gray,
                            scaleFactor=1.1,
                            minNeighbors=5,
                            minSize=(30, 30),
                            flags=cv2.CASCADE_SCALE_IMAGE)
print('Detected ', len(faces), " face")
# 标记位置
for (x, y, w, h) in faces:
    img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 1)
    # cv2.circle(img, (int((x + x + w) / 2), int((y + y + h) / 2)), int(w / 2), (0, 255, 0), 1)
    roi_gray = gray[y: y + h, x: x + w]
    roi_color = img[y: y + h, x: x + w]
    eyes = eye_cascade.detectMultiScale(roi_gray)
    for (ex, ey, ew, eh) in eyes:
        cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 1)
label = 'Result: Detected ' + str(len(faces)) +" faces !"
cv2.putText(img, label, (10, 20),
                        cv2.FONT_HERSHEY_SCRIPT_COMPLEX, 
                        0.8, (0, 0, 0), 1)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

【下载链接】


   若您想获得博文中涉及的实现完整全部程序文件(包括图片,py, xml文件等),这里已打包上传至博主的CSDN下载资源中,下载后运行test.py文件即可运行。文件下载链接如下:


相关文章
|
1月前
|
算法 计算机视觉
OpenCV(四十三):Shi-Tomas角点检测
OpenCV(四十三):Shi-Tomas角点检测
25 0
|
1月前
|
计算机视觉
OpenCV(三十八):二维码检测
OpenCV(三十八):二维码检测
46 0
|
1月前
|
编解码 计算机视觉
OpenCV(三十六):霍夫直线检测
OpenCV(三十六):霍夫直线检测
25 0
|
1月前
|
计算机视觉 索引
OpenCV(三十五):凸包检测
OpenCV(三十五):凸包检测
24 0
|
2月前
|
监控 安全 自动驾驶
基于python的室内老人实时摔倒智能监测系统-跌倒检测系统(康复训练检测+代码)
基于python的室内老人实时摔倒智能监测系统-跌倒检测系统(康复训练检测+代码)
79 1
|
1月前
|
存储 资源调度 算法
Opencv(C++)系列学习---SIFT、SURF、ORB算子特征检测
Opencv(C++)系列学习---SIFT、SURF、ORB算子特征检测
|
1月前
|
存储 算法 计算机视觉
OpenCV(四十二):Harris角点检测
OpenCV(四十二):Harris角点检测
28 0
|
7天前
|
数据采集 存储 安全
python检测代理ip是否可用的方法
python检测代理ip是否可用的方法
|
7天前
|
机器学习/深度学习 算法 自动驾驶
opencv python 图片叠加
【4月更文挑战第17天】
|
16天前
|
编解码 计算机视觉 Python
opencv 图像金字塔(python)
opencv 图像金字塔(python)

热门文章

最新文章