HAAR与DLib的实时人脸检测之实现与对比
人脸检测方法有许多,比如opencv自带的人脸Haar特征分类器和dlib人脸检测方法等。
对于opencv的人脸检测方法,优点是简单,快速;存在的问题是人脸检测效果不好。正面/垂直/光线较好的人脸,该方法可以检测出来,而侧面/歪斜/光线不好的人脸,无法检测。因此,该方法不适合现场应用。而对于dlib人脸检测方法采用64个特征点检测,效果会好于opencv的方法识别率会更高,本文会分别采用这几种方法来实现人脸识别。那个算法更好,跑跑代码就知道。
实时图像捕获
首先在进行人脸识别之前需要先来学点OpenCV的基础,起码知道如何从摄像头获取当前拍到的图像吧。OpenCV其实很简单,接下来的代码就是最基本的起步点。
第一步:打开本机上的摄像头,实例化VideoCapture
类
camera = cv2.VideoCapture(0)
开始第一帧图像的捕获,这个方法用来测试当前的摄像头是否可用
success, frame = camera.read()
当success
返回真时表示开始捕捉图像,反则表示摄像头打开失败,接下来就用最少的代码来打开摄像头并将当前的图像直接显示到一个窗口上,具体代码结构如下:
# coding=utf-8
# ~/learn_face/cv_base.py
from __future__ import print_function
import cv2
cameraCapture = cv2.VideoCapture(0)
success, frame = cameraCapture.read()
while success and cv2.waitKey(1) == -1:
success, frame = cameraCapture.read()
#TODO:在此处可放置各种对当前每一帧图像的处理
cv2.imshow("Camera", frame)
cameraCapture.release()
cv2.destroyAllWindows()
将上述代码存为opencv_base.py
然后在命令行直接运行查看效果:
python opencv_base.py
效果如下:
HAAR 分类器
基于Haar特征的cascade分类器(classifiers) 是Paul Viola和 Michael Jone在2001年,论文”Rapid Object Detection using a Boosted Cascade of Simple Features”中提出的一种有效的物品检测(object detect)方法。它是一种机器学习方法,通过许多正负样例中训练得到cascade方程,然后将其应用于其他图片。
在OpenCV3的源码的data
目录中就可以找到已训练好的HAAR算法模型,至HAAR算法的各种细节与理论有兴趣的直接去Google或者百度吧,一搜一大堆。花时间看一堆理论不如直接上代码,由代码直接理解这些复杂理论的应用更适合开发人员,毕竟我们不是数学家。
使用HAAR模型识别图像中的人脸其实只要三步走,即使你对深度网络一点不懂也没关系,再复杂的理论到最终不过是一个方法调用罢了,了解清楚其中的原理就好。
第一步:初始化分类器并载入已训练好的HARR模型:
face_cascade = cv2.CascadeClassifier(r'haarcascade_frontalface_default.xml')
第二步: 通过cv2.cvtColor
方法将当前的图像进行灰度化处理,简化图像的信息:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
第三步:然后将灰度化后的图像输入到分类器进行预判:
faces = face_cascade.detectMultiScale(gray, 1.3, 5) #识别人脸
只要faces
数组的长度大于一就表示检测到当前画面中检测到人脸,反之亦然。简单来说其实人脸检测已经完成,
最后,为了我们可以知道识别出来的结果,我们可以将脸用方框给圈出来,这里写个方法来圈脸:
def mark_face(img,x,y,w,h):
return cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
以下为本例的全部代码:
# coding=utf-8
# ~/learn_face/cv_haar.py
from __future__ import print_function
import cv2
def mark_face(img, x, y, w, h):
return cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
cameraCapture = cv2.VideoCapture(0)
success, frame = cameraCapture.read()
face_cascade = cv2.CascadeClassifier(r'haarcascade_frontalface_default.xml') # 1.载入模型
while success and cv2.waitKey(1) == -1:
success, frame = cameraCapture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 2.生成灰度图
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5
) # 3.进行识别
[mark_face(frame, *args) for args in faces] #画出识别的结果
cv2.imshow("Camera", frame)
cameraCapture.release()
cv2.destroyAllWindows()
以下是运行效果:
运行起来就会觉得HAAR的识别效果不怎么样,稍微动一下就很会识别不了。
Dlib
接下来我们试试用DLib这个老牌的专做人脸识别起家的C++库来试试,Dlib是一个跨平台的C++公共库,除了线程支持,网络支持,提供测试以及大量工具等等优点,Dlib还是一个强大的机器学习的C++库,包含了许多机器学习常用的算法。同时支持大量的数值算法如矩阵、大整数、随机数运算等等。Dlib同时还包含了大量的图形模型算法。最重要的是Dlib的文档和例子都非常详细。
与HAAR分类器的检测方法相比dLib就简单得多了,只需要用dlib自带的人脸检测器detector
就够了,连模型都省了!之前的代码两步就能完成
第一步:实例化 detector
:
detector = dlib.get_frontal_face_detector()
第二步:进行人脸检测
faces = detector(frame, 1)
That's all! 是不是很简单?
以下是本例的全部代码:
# coding=utf-8
# ~/learn_face/cv_dlib.py
from __future__ import print_function
import cv2
import dlib
cameraCapture = cv2.VideoCapture(0)
success, frame = cameraCapture.read()
detector = dlib.get_frontal_face_detector()
while success and cv2.waitKey(1) == -1:
success, frame = cameraCapture.read()
faces = detector(frame, 1)
for k, d in enumerate(faces):
frame = cv2.rectangle(frame, (d.left(), d.top()),
(d.right(), d.bottom()), (255, 0, 0), 2)
cv2.imshow("Camera", frame)
cameraCapture.release()
cv2.destroyAllWindows()
运行上述代码后会发现dlib的效果真的比HAAR的检测效果要好很多!不管头怎么转都能瞬间识别到,画出来的矩形框都不带闪的!
特征点检测
接下来我们用DLib的特征点提取器detector
所识别出来的人脸轮廓点给标记出来。关键点(landmarks)提取需要一个特征提取器predictor
,为了构建特征提取器,预训练模型必不可少。除了自行进行训练外,可以使用官方提供的一个模型。该模型可从dlib sourceforge 库下载,此模型是从人脸中提出64个特征点进行检测,其准确度相当高。
具体实现思路如下:
- 第一步:生成灰度图
- 第二步:生成直方图
- 第三步:进行检测
以下为全部代码
# coding=utf-8
# ~/learn_face/landmark.py
import cv2
import dlib
cameraCapture = cv2.VideoCapture(0)
success, frame = cameraCapture.read()
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(
"shape_predictor_68_face_landmarks.dat")
while success and cv2.waitKey(1) == -1:
success, frame = cameraCapture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #生成灰度图
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) #生成直方图
clahe_image = clahe.apply(gray)
detections = detector(clahe_image, 1)
for k, d in enumerate(detections):
shape = predictor(clahe_image, d) # 获取坐标
for i in range(1, 68): # 每张脸都有68个识别点
cv2.circle(frame, (shape.part(i).x, shape.part(i).y), 1, (0, 0, 255),
thickness=2)
cv2.imshow("Camera", frame)
cameraCapture.release()
cv2.destroyAllWindows()
运行效果:
小结
我在macBookPro上跑以上的代码在速度是上没有什么很大区别的,至少不会产生卡顿。但如果换将代码植到树莓3和树莓Zero上区别就明显了,HAAR分类器在树梅Zero上的运行时间平均在1.2s左右,而dlib则需要8s。至于准确率Dlib又明显会优于HAAR。
参考阅读
HAAR与DLib的实时人脸检测之实现与对比的更多相关文章
- Python 3 利用 Dlib 实现摄像头实时人脸检测和平铺显示
1. 引言 在某些场景下,我们不仅需要进行实时人脸检测追踪,还要进行再加工:这里进行摄像头实时人脸检测,并对于实时检测的人脸进行初步提取: 单个/多个人脸检测,并依次在摄像头窗口,实时平铺显示检测到的 ...
- Python 3 利用 Dlib 实现摄像头人脸检测特征点标定
0. 引言 利用 Python 开发,借助 Dlib 库捕获摄像头中的人脸,进行实时人脸 68 个特征点标定: 支持多张人脸: 有截图功能: 图 1 工程效果示例( gif ) 图 2 工程效果示例( ...
- 基于Haar特征的Adaboost级联人脸检测分类器
基于Haar特征的Adaboost级联人脸检测分类器基于Haar特征的Adaboost级联人脸检测分类器,简称haar分类器.通过这个算法的名字,我们可以看到这个算法其实包含了几个关键点:Haar特征 ...
- 照片美妆---基于Haar特征的Adaboost级联人脸检测分类器
原文:照片美妆---基于Haar特征的Adaboost级联人脸检测分类器 本文转载自张雨石http://blog.csdn.net/stdcoutzyx/article/details/3484223 ...
- Haar、pico、npd、dlib等多种人脸检测特征及算法结果比较
原文:opencv.pico.npd.dlib.face++等多种人脸检测算法结果比较 NDP检测结果: 结果分析: Pico(Pixel Intensity Comparison-based Obj ...
- 实时人脸检测 (Real-Time Face Detection)
源地址:http://blog.sina.com.cn/s/blog_79b67dfe0102uzra.html 最近需要用到人脸检测,于是找了篇引用广泛的论文实现了一下:Robust Real-Ti ...
- opencv+python实时人脸检测、磨皮
import numpy as np import cv2 cap = cv2.VideoCapture(0) face_cascade = cv2.CascadeClassifier("d ...
- win10+anaconda+cuda配置dlib,使用GPU对dlib的深度学习算法进行加速(以人脸检测为例)
在计算机视觉和机器学习方向有一个特别好用但是比较低调的库,也就是dlib,与opencv相比其包含了很多最新的算法,尤其是深度学习方面的,因此很有必要学习一下.恰好最近换了一台笔记本,内含一块GTX1 ...
- Python 3 利用 Dlib 实现人脸检测和剪切
0. 引言 利用 Python 开发,借助 Dlib 库进行人脸检测 / face detection 和剪切: 1. crop_faces_show.py : 将检测到的人脸剪切下来,依次排序平 ...
随机推荐
- 洗礼灵魂,修炼python(65)--爬虫篇—BeautifulSoup:“忘掉正则表达式吧,我拉车养你”
前面解析了正则表达式,其实内容还挺多的对吧?确实挺适用的,不仅是python,其他语言或者web前端后端基本都要掌握正则表达式知识,但是你说,这么多,要完全的掌握,灵活运用的话,得搞多久啊?并且如果一 ...
- jvm程序执行慢诊断手册
生产环境最多的几种事故之一就是程序执行慢,如果是web服务的话,表现就是响应时间长.本文分享,从业多年形成的排查守则. 诊断步骤 系统资源查看 首先是系统资源查看,而且必须是在第一步.因为很多事故都是 ...
- windows下安装mysql
windows 下安装mysql 1.先下载好 mysql5.7 版本的安装包,可以去官网自己下载,也可以从我的百度云分享 里面下载: 链接: https://pan.baidu.com/s/1VXk ...
- EOS之记事本智能合约
EOS记事本智能合约 本次分享的内容是一个记事本合约,调用合约中的写入动作可以将文本和作者保存到数据库中,通过记事本合约来学习EOS智能合约数据存储当中的主键自增. 合约动作 写入动作 记事本合约必须 ...
- Linux 自动化部署Rsyslog服务
Linux 自动化部署Rsyslog服务 源码如下: #/bin/bash #该脚本用于自动化部署Ryslog服务配置 #作者:雨中落叶 #博客:https://www.cnblogs.com/yuz ...
- java基础学习总结——equals方法
一.equals方法介绍 1.1.通过下面的例子掌握equals的用法 package cn.galc.test; public class TestEquals { public static vo ...
- Java入门(一):Hello World !
前言 从今天开始,准备写Java Web开发的系列文章,毕竟自己主攻的还是Java方向,Python只是业余学习的兴趣使然,在第二技能还没有培养成熟前,做好第一技能的巩固和提高是很有必要的.从正式入行 ...
- 《Java大学教程》—第8章 通过继承扩展类
8.2 继承(inheritance):继承是指在类之间共享属性和方法.继承关系是一种层次关系.在继承关系中位于顶部的类称为超类(或基类),位于下面的类称为子类(或派生类).类型转换(type ...
- 【C编程基础】多线程编程
基础知识 1.基本概念 (1)线程,即轻量级进程(LWP:LightWeight Process),是程序执行流的最小单元. 线程是进程中的一个实体,是被系统独立调度和分派的基本单位. (2)线程同步 ...
- linux中如何查看进程的启动时间
ps -p PID -o lstart 其中PID是进程的pid [root@lvs-a logs]# -o lstart STARTED Tue Oct ::