haar特征_Python-OpenCV 22. 人脸及面部特征检测

本文学习资源来自《机器学习实践指南 案例应用解析》

一、人脸辨识概念

生物特征识别(BIOMETRICS) 技术,是指通过计算机利用人体所固有的生理特征(指纹、虹膜、面相、DNA等)或行为特征(步态、击键习惯等)来进行个人身份鉴定的技术。
——百度百科
人脸识别属于生物特征识别技术中的一种。

二、OpenCV的人脸定位

OpenCV的接口可以实现人脸检测函数,定义了具体可跟踪对象类型的数据文件。
Haar级联分类器,通过对比分析相邻图像区域来判断给定图像或子图像与已知对象是否匹配。两个图像的相似程度可以通过它们对应特征的欧式距离来度量。距离可能以空间坐标或颜色坐标来定义。类Haar特征是一种用于实现实时人脸跟踪的特征。每个类Haar特征都描述了相邻图像区域的对比模式。例如,边,顶点和细线都能生成具有判断性的特征。

Haar级联级具有尺度不变性,换句话说,它在尺度变化上具有鲁棒性。但是,opencv的Haar级联不具有旋转不变性。

三、OpenCV的人脸检测函数说明

OpenCV1 中的函数:cvHaarDetectObjects

OpenCV2中的函数:detectMultiScale

detectMultiScale函数可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示),函数由分类器对象调用:
函数原型:

void detectMultiScale(  const Mat& image,  CV_OUT vector& objects,  double scaleFactor = 1.1,  int minNeighbors = 3,  int flags = 0,  Size minSize = Size(),  Size maxSize = Size() ); 
  • 参数1:image–待检测图片,一般为灰度图像加快检测速度;
  • 参数2:objects–被检测物体的矩形框向量组;
  • 参数3:scaleFactor–表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;
  • 参数4:minNeighbors–表示构成检测目标的相邻矩形的最小个数(默认为3个)。
    如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。
    如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,
    这种设定值一般用在用户自定义对检测结果的组合程序上;
  • 参数5:flags–要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为
    CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,
    因此这些区域通常不会是人脸所在区域;
  • 参数6、7:minSize和maxSize用来限制得到的目标区域的范围。

四、使用OpenCV的人脸检测函数

在opencv源代码的副本中会有一个文件夹data/haarcascades,该文件夹包括了所有opencv的人脸检测的xml文件,这些文件可用于检测静止图像,视频和摄像头所得到图像中的人脸。

  • 人脸检测器(默认):haarcascade_frontalface_default.xml
  • 人脸检测器(快速Harr):haarcascade_frontalface_alt2.xml
  • 人脸检测器(侧视):haarcascade_profileface.xml
  • 眼部检测器(左眼):haarcascade_lefteye_2splits.xml
  • 眼部检测器(右眼):haarcascade_righteye_2splits.xml
  • 嘴部检测器:haarcascade_mcs_mouth.xml
  • 鼻子检测器:haarcascade_mcs_nose.xml
  • 身体检测器:haarcascade_fullbody.xml
  • 人脸检测器(快速LBP):lbpcascade_frontalface.xml

首先,下载OpenCV库:

git clone https://github.com/opencv/opencv

1. 静态人脸检测

# -*- coding: utf-8 -*-# coding=utf-8import cv2print('loading...')OPCV_PATH = r"D:/tools/opencv/sources"classfier = cv2.CascadeClassifier(OPCV_PATH + "/data/haarcascades/haarcascade_frontalface_alt.xml")img = cv2.imread('test.jpg')gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)faces = classfier.detectMultiScale(gray, 1.2, 5)for (x, y, w, h) in faces: img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)cv2.namedWindow('Vikings Detected')cv2.imshow('Vikings Detected', img)cv2.waitKey(0)

运行结果:

4cb38ff645dbff307add564af401d9e7.png

这里使用的是 haarcascade_frontalface_alt 前脸检测器,测试可发现:

  • 正面检测较好,但侧脸、位置不正检测效果不佳
  • 人脸有遮挡时检测效果不佳

这张图的检测结果看得可以更明显:

5783557e0995744dd40e0c9572b8b4b7.png

2. 人眼检测

# -*- coding: utf-8 -*-# coding=utf-8import cv2print('loading...')OPCV_PATH = r"D:/tools/opencv/sources"classfier = cv2.CascadeClassifier(OPCV_PATH + "/data/haarcascades/haarcascade_eye.xml")img = cv2.imread('test.jpg')gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)faces = classfier.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5, minSize=(5, 5), flags=cv2.CASCADE_SCALE_IMAGE)for (x, y, w, h) in faces: cv2.circle(img, (int((x + x + w) / 2), int((y + y + h) / 2)), int(w / 2), (0, 255, 0), 2)cv2.namedWindow('Vikings Detected')cv2.imshow('Vikings Detected', img)cv2.waitKey(0)
b17571c42b03247230c8e503c3500d6d.png

3. 视频人脸检测

# -*- coding: utf-8 -*-# coding=utf-8import numpy as npimport cv2OPCV_PATH = r"D:/tools/opencv/sources/data/haarcascades/"# 人脸识别分类器faceCascade = cv2.CascadeClassifier(OPCV_PATH + 'haarcascade_frontalface_default.xml')# 识别眼睛的分类器eyeCascade = cv2.CascadeClassifier(OPCV_PATH + 'haarcascade_eye_tree_eyeglasses.xml')# 开启摄像头cap = cv2.VideoCapture(0)ok = Truecount = 0while ok: # 读取摄像头中的图像,ok为是否读取成功的判断参数 ok, img = cap.read() # 转换成灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 人脸检测 faces = faceCascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=5, minSize=(32, 32) ) result = [] # 在检测人脸的基础上检测眼睛 for (x, y, w, h) in faces: fac_gray = gray[y: (y + h), x: (x + w)] result = [] eyes = eyeCascade.detectMultiScale(fac_gray, 1.3, 2) # 眼睛坐标的换算,将相对位置换成绝对位置 for (ex, ey, ew, eh) in eyes: result.append((x + ex, y + ey, ew, eh)) # 画矩形 for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) for (ex, ey, ew, eh) in result: cv2.rectangle(img, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2) cv2.imshow('video', img) if len(result): count += 1 cv2.imwrite('./%s.png' % str(count), img) k = cv2.waitKey(1) if k == 27 or count > 20: # press 'ESC' to quit breakcap.release()cv2.destroyAllWindows()

这里检测到即保存图片,图片大于20张程序停止。

b8257a2cf5f12d9a5dac601b872f5d0b.png

4. 从监控摄像头获取图像检测

只需要把上面代码里:

cap = cv2.VideoCapture(url) 

VideoCapture的参数改为rtsp地址。
另外网络情况不佳时,需要把视频接收帧存队列、处理帧独立线程,避免解码失败造成程序退出。

总结:
以上方式检测仅从原理演示人脸检测,其效果远达不到商业使用的要求。

本文部分图片素材来自互联网,如有侵权请告知,我将立刻予以删除。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值