opencv目标检测,用10行代码自己写个人脸识别程序

作者:计算机网络

The English version of this blog at here :

python实现人脸识别代码,python人脸代码

从实时视频流中识别出人脸区域,从原理上看,其依然属于机器学习的领域之一,本质上与谷歌利用深度学习识别出猫没有什么区别。程序通过大量的人脸图片数据进行训练,利用数学算法建立建立可靠的人脸特征模型,如此即可识别出人脸。幸运的是,这些工作OpenCV已经帮我们做了,我们只需调用对应的API函数即可,先给出代码:

#-*- coding: utf-8 -*-

import cv2
import sys
from PIL import Image

def CatchUsbVideo(window_name, camera_idx):
  cv2.namedWindow(window_name)

  #视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
  cap = cv2.VideoCapture(camera_idx)        

  #告诉OpenCV使用人脸识别分类器
  classfier = cv2.CascadeClassifier("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml")

  #识别出人脸后要画的边框的颜色,RGB格式
  color = (0, 255, 0)

  while cap.isOpened():
    ok, frame = cap.read() #读取一帧数据
    if not ok:      
      break     #将当前帧转换成灰度图像    grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)         

    #人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
    faceRects = classfier.detectMultiScale(grey, scaleFactor = 1.2, minNeighbors = 3, minSize = (32, 32))
    if len(faceRects) > 0:      #大于0则检测到人脸                  
      for faceRect in faceRects: #单独框出每一张人脸
        x, y, w, h = faceRect    
        cv2.rectangle(frame, (x - 10, y - 10), (x   w   10, y   h   10), color, 2)

    #显示图像
    cv2.imshow(window_name, frame)    
    c = cv2.waitKey(10)
    if c & 0xFF == ord('q'):
      break    

  #释放摄像头并销毁所有窗口
  cap.release()
  cv2.destroyAllWindows() 

if __name__ == '__main__':
  if len(sys.argv) != 2:
    print("Usage:%s camera_idrn" % (sys.argv[0]))
  else:
    CatchUsbVideo("识别人脸区域", int(sys.argv[1]))

先看一下程序输出结果:

图片 1

程序正确的识别出了我的脸,加上空白行不到50行代码,还是很简单的。当然,绝大部分的工作OpenCV已经默默地替我们做了,所以我们用起来才这么简单。关于代码有几个地方需要重点交代,首先就是人脸分类器这行:

#告诉OpenCV使用人脸识别分类器
classfier = cv2.CascadeClassifier("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml")

这行代码指定OpenCV选择使用哪种分类器(注意,一定习惯分类这个说法,ML的监督学习研究的就是各种分类问题),OpenCV提供了多种分类器:

图片 2

上图为我的电脑上安装的OpenCV3.2提供的所有分类器,有识别眼睛的(甚至包括左右眼),有识别身体的,有识别笑脸的,甚至还有识别猫脸的,有兴趣的可以逐个试试。关于人脸识别,OpenCV提供多个分类器选择使用,其中haarcascade_frontalface_alt_tree.xml是最严格的分类器,光线、带个帽子都有可能识别不出人脸。其它的稍微好点,default那个识别最宽松,某些情况下我家里的灯笼都会被识别成人脸;)。另外安装环境不同,分类器的安装路径也有可能不同,请在安装完OpenCV后根据分类器的实际安装路径修改代码。另外再多说一句,如果我们想构建自己的分类器,比如检测火焰(火灾报警)、汽车(确定路口汽车数量),我们依然可以使用OpenCV训练构建,详细说明参见OpenCV的官方文档。

接下来解释如下几行代码:

#人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
faceRects = classfier.detectMultiScale(grey, scaleFactor = 1.2, minNeighbors = 3, minSize = (32, 32))
if len(faceRects) > 0:     #大于0则检测到人脸                  
  for faceRect in faceRects: #单独框出每一张人脸
    x, y, w, h = faceRect    
    cv2.rectangle(frame, (x - 10, y - 10), (x   w   10, y   h   10), color, 2)

其中classfier.detectMultiScale()即是完成实际人脸识别工作的函数,该函数参数说明如下:

grey:要识别的图像数据(即使不转换成灰度也能识别,但是灰度图可以降低计算强度,因为检测的依据是哈尔特征,转换后每个点的RGB数据变成了一维的灰度,这样计算强度就减少很多)

scaleFactor:图像缩放比例,可以理解为同一个物体与相机距离不同,其大小亦不同,必须将其缩放到一定大小才方便识别,该参数指定每次缩放的比例

minNeighbors:对特征检测点周边多少有效点同时检测,这样可避免因选取的特征检测点太小而导致遗漏

minSize:特征检测点的最小值

对同一个画面有可能出现多张人脸,因此,我们需要用一个for循环将所有检测到的人脸都读取出来,然后逐个用矩形框框出来,这就是接下来的for语句的作用。Opencv会给出每张人脸在图像中的起始坐标(左上角,x、y)以及长、宽(h、w),我们据此就可以截取出人脸。其中,cv2.rectangle()完成画框的工作,在这里我有意识的外扩了10个像素以框出比人脸稍大一点的区域。cv2.rectangle()函数的最后两个参数一个用于指定矩形边框的颜色,一个用于指定矩形边框线条的粗细程度。

好了,人脸识别的事说清楚了,下一篇该讲讲如何准备训练数据了,只有训练数据足够多,我们的程序才能识别出这是谁,而不是无论青红皂白框个人脸就完事。

总结

以上就是本文关于python实现人脸识别代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:python通过socket实现多个连接并实现ssh功能详解、Python基础练习之用户登录实现代码分享、Python入门之三角函数全解【收藏】等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!

从实时视频流中识别出人脸区域,从原理上看,其依然属于机器学习的领域之一,本质上与谷歌利用...

最近在做移动端的视频流目标检测,配置opencv4Android,这一块在opencv官方文档上有些说明文档,另外learning opencv3的章节object detection也值得一看。

   本篇介绍图像处理与模式识别中最热门的一个领域——人脸检测(人脸识别)。人脸检测可以说是学术界的宠儿,在不少EI,SCI高级别论文都能看到它的身影。甚至很多高校学生的毕业设计都会涉及到人脸检测。当然人脸检测的巨大实用价值也让很多公司纷纷关注,很多公司都拥有这方面的专利或是开发商业产品出售。

最近在研究CV的一些开源库,有一个体会就是在此领域,除了一些非常学术的机器学习, 深度学习等概念外,其实还有一些很有趣的现实的应用场景。比如之前很流行的微软的 , 你使用自己指定或者上传的照片进行面部识别猜年龄。 如下图所示:

前言

目标检测,就是判断图片中是否包含特定物体以及物体在像素空间上的位置。这里,我们关注几种机器学习技术的目标检测手段。

    在OpenCV中,人脸检测也是其热门应用之一。在OpenCV的特征检测专题就详细介绍了人脸检测的原理——通过Haar特征来识别是否为人脸。Haar特征检测原理与Haar特征分类器的训练放到下一篇《【OpenCV入门指南】第十四篇  Haartraining》来讲,本篇主要介绍如何在OpenCV中使用Haar特征分类器来对图像中的人脸进行检测和识别。下面将分成五步来详细示范如何在OpenCV中进行人脸识别:

图片 3

1.基于树的目标检测技术

在当前的opencv库里有两种检测器,cascade classifier,源自Viola 和 Jones在人脸检测上非常成功的算法,详见Viola, Paul, and Michael Jones. “Rapid object detection using a boosted cascade of simple features.” Computer Vision and Pattern Recognition, 2001. CVPR 2001. Proceedings of the 2001 IEEE Computer Society Conference on. Vol. 1. IEEE,2001.第二种是soft cascade,一种提供了新途径的演化的算法,并在大多实例上比cascade classifier有更健壮的分类。两种算法都可以用到多目标检测上,一般而言,具有严格结构和丰富纹理的物体(刚性物体)响应更好。
这些算法不仅封装了基学习器的函数,还包含了学习器的输入或是输出的预处理的方法。当然,这些算法不像是opencv中的基学习器,有统一的接口。它建立了boost筛选式级联分类器。它与ML库中其他部分相比,有不同的格局,因为它是在早期开发的,并完全可用于人脸检测。通常由算法的发明者提供给opencv,因此接口更像是算法的原始实现。

    一.人脸的Haar特征分类器是什么

细想一下这个很吸引眼球的程序,其实技术本身打散了就包括两大块,一是从图片中扫描并进行面部识别,二是对找到的人脸根据算法去猜个年龄。大家可以猜猜实现第一个功能需要多少核心代码量?其实不用上万行,在这里我就使用短短几行代码(去除空格换行什么的,有效代码只要10行)就实现一个高大上面部识别的功能。在此文容我细述一下具体实现代码以及我对机器识别图像领域技术的理解。

1.1 Cascade Classifiers

Cascade Classifier由一个重要的概念构建,boosted rejection cascade。它在opencv库里有不同的格式,因为它一开始是由一个成熟的人脸检测的应用发展而来, 随后才演化的更普遍。这里我们介绍它的详细原理和怎样应用到人脸检测和其他物体上。

计算机视觉是一个涉及广泛而又发展迅速的领域,所以opencv中某个特定技术很容易发展过时,之前的人脸检测器(Haar classifier)就是这样,但人脸检测又有巨大的需求,因此需要一个不错的基线技术供使用,而且人脸检测是建立在最经常使用的分类器boosting上,因此更加通用。事实上,一些公司使用了opencv中的“人脸”检测器来检测“基本刚性的”物体(脸,汽车,自行车,人体)。通过成千上万的物体的各个角度的训练图像,训练出新的分类器,这个技术被用来设计目前最优的检测算法。因此,对于此类识别任务,Haar分类器是一个有用的工具。

cascade classifier,又被称为Viola-Jones detector,最开始,这种算法和他的opencv实现仅支持Haar小波这种特定的特征。之后,由Rainer Lienhart 和 Jochen Maydt扩展,详见Lienhart, Rainer, and Jochen Maydt. “An extended set of haar-like features for rapid object detection.” Proceedings 2002 International Conference on Image Processing. Vol. 1. IEEE, 2002.使用对角特征,更普遍地,称为“Haar-like” 特征,在opencv3.x中,又发展成使用local binary patterns(LBP)。
opencv的cascade classifier实现有两层,第一层是特征检测,封装了特征计算,第二层是boosted cascade,计算得到的特征的矩形区域的和与差,boosting分类器与特征的计算层无关。

    二.在哪找人脸的Haar特征分类器

面部识别,刷脸

人脸识别技术大家应该都不陌生,之前大家使用的数码相机,或者现在很多手机自带的相机都有人脸识别的功能。其效果就像是下图这样。近的看,剁手节刚刚过了没有多久 , 背后的马老板一直在力推的刷脸支付也是一个此领域的所谓“黑科技”。比如在德国汉诺威电子展上,马云用支付宝“刷脸”买了一套纪念邮票。人脸识别应用市场也从爆发。随后,各大互联网巨头也纷纷推出了刷脸相关的应用。

图片 4

如果要加个定义,人脸识别又叫做人像识别、面部识别,是一种通过用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部的一系列相关技术。

OK,长话短说,先上 干货 ,下面就是此程序的带注释 版本,完整的程序以及相关配套文件可以在 这个github库 中找到,有兴趣可以fork 下来玩玩。下面是整个程序的代码样子,后面我会逐行去解释分析。

图片 5

就这短短的十行代码代码?seriously?“有图有真相”,我们先来看下运行的效果:

1.1.1 Haar-like features

类Haar特征描述如下图,

图片 6

类Haar特征(矩形和旋转矩形特征都很容易从积分图中算出)

在所有缩放尺度下,这些特征组成了boosting分类器使用的全部“原材料”。他们从原始灰度图像的积分图中快速计算得出。

opencv可以使用cv::integral()函数轻松计算积分图,积分图是一种数据结构,可以实现子区域的快速求和。这样的求和在很多应用中是有用的,最显著的是人脸识别和相关算法的Haar小波。
opencv支持积分图的三种变化。分别是sum, square-sum, tilted-sum.每一种的输出和输入图像尺寸一致。利用这些积分图,可以计算图像的任意直立或倾斜的矩形区域的和,均值和标准差。在这种方式下,就可能进行快速模糊、梯度估计、计算均值和标准差,甚至为各种窗口大小执行快速的可变窗块相关计算。

图片 7

积分图的计算

三种不同的积分图在C API中仅以他们的参数加以区分。

图片 8

Standard Summation Integral

图片 9

Squared Summation Integral


如果输入图片的尺寸是W*H,那么输出则是(W 1)*(H 1)。
当前,opencv中仅支持两种特征。原始的Haar小波(包含对角特征)和LBP。

    三.怎么用人脸的Haar特征分类器

首先是原始的图片

图片 10

1.1.2 Local binary pattern features

LBP是一种用来描述图像局部纹理特征的算子,被用于Viola-Jones检测器,回想Haar小波,它是在一小块邻域上通过小波变换的特征向量,而LBP在构造特征向量与此不同,在一个长宽都为3的倍数的矩形上,将它分割成不相重叠的3*3的小块,在每一个小块上,用积分图计算像素和,然后将中心点像素与周围8个像素点比较得到一个8位的特征值,用来描述相应矩形的特征。

图片 11

image.png

    四.人脸识别示例代码

运行程序后识别出面部并高亮显示的结果

请注意 K歌二人组 的脸上的红色框框,这就是上面十行代码的成果。

图片 12

1.1.3 Training and pretrained detectors

opencv提供了一套预训练目标识别的文件,也有代码允许你训练存储新的检测器的目标模型。如果不够用,在opencv存储目录里apps文件夹下还有traincascade的应用,你可以用它来训练任何刚性物体的检测器,但稳定性因物变化。
预训练目标的文件在.../opencv/data/haarcascades和.../opencv/data/lbpcascades下面,其中正面人脸识别效果最好的是haarcascade_frontalface_alt2.xml,而侧脸却难以用该方法获得准确的检测结果。

    五.人脸识别程序运行结果

准备工作

因为此程序使用是的Python,因此你需要去安装Python。这里就不赘述了。除此之外,还需要安装 OpenCV ( OpenCV正如其名,是一个开源的机器识别的深度学习框架。这是Intel实验室里的一个俄罗斯团队创造的,目前在开源社区非常的活跃。

特别提一下,对于Mac的用户,推荐使用brew去安装 (下面第一条语句可能会执行报错,我当时也是搞了好久。如果遇到第一条命令不过可以通过文尾的方式联系作者)

brew tap homebrew/sciencebrew install opencv

安装完成之后,在python的命令行中输入如下代码验证,如果没有报错就说明安装好了。

>>> import cv2
1.2 监督学习和Boosting理论

opencv中的cascade分类器是一种监督学习,Viola-Jones检测器使用adaboost,也叫作rejection cascade,cascade是一系列的节点,每一个节点是独立的adaboost分类树,图像上的一个子窗口以一种特定顺序在所有cascade上测试,只有通过了所有分类器的窗口才被视作是目标。
每一个节点都被设计成为有高检测率(99.9%)和低假正率(大致50%),每一个节点里,得到没有在图片里的结果就可以结束计算,然后最终宣称图片上没有目标。

 

程序代码“庖丁解牛”

# -*- coding: utf-8 -*-import cv2,sys
  • 由于这里注释及窗口标题中使用了中文,因此加上utf-8字符集的支持
  • 引入Opencv库以及Python的sys内建库,用于解析输入的图片参数
inputImageFile=sys.argv[1]
  • 在运行程序时将需要测试的照片文件名作为一个参数传进来
faceClassifier=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
  • 加载OpenCV中自带预先培训好的人脸识别层级分类器 HAAR Casscade Classifier,这个会用来对我们输入的图片进行人脸判断。

这里有几个在深度学习及机器图像识别领域中的几个概念,稍微分析一下,至于深入的知识,大家可以自行搜索或者联系作者。

1.2.1 Boosting in the Haar cascade

对于Viola-Jones rejection cascade,每一个节点都是组合的弱学习器,然后通过boosting,组成一个强学习器。这些独立的弱学习器通常是深度为1的决策树,即单层决策树。单层决策树通常只做一个决定,按照以下格式:特征h里的值v,是大于阈值t,还是小于?“yes”表示物体的存在,“no”表示没有。

图片 13

单层决策树

Viola-Jones分类器的Haar特征或LBP特征的数量在每一层节点都可以设置,但大多通常是单一特征的决策,有些场景最多三个特征。然后通过迭代提升将这些弱学习器进行加权组合。

图片 14

boosting

在训练一开始,需要设置在每个节点上能最优化分输入的阈值tw,然后用累积误差来计算权重参数αw。在传统的adaboost里,每一个特征向量(数据点)每次迭代时也需要重新分配权重。

一.人脸的Haar特征分类器是什么

人脸的Haar特征分类器就是一个XML文件,该文件中会描述人脸的Haar特征值。当然Haar特征的用途可不止可以用来描述人脸这一种,用来描述眼睛,嘴唇或是其它物体也是可以的。

 

Classifer

在机器深度学习领域,针对识别不同物体都有不同的classifier,比如有的classifier来识别洗车,还有识别飞机的classifier,有classifier来识别照片中的笑容,眼睛等等。而我们这个例子是需要去做人脸识别,因此需要一个面部识别的classifier。

1.2.2 Rejection cascades.

下图展示了Rejection cascades的流程,由许多的boosted分类器组成,每个节点Fj包含了整个决策树桩的集合,每个节点都有个很高的检测率(99.9%),但可能也有50%的非目标检测失误,但这不影响,想象20个节点后,检测率为0.99920 ≈ 98%,而假正率仅为0.520 ≈ 0.0001%!

图片 15

Rejection cascades

像之前提及的,这个技术实现了人脸检测但不限于人脸,在大多数刚性物体上都表现的很好,但侧脸或者说是车的角落位置则不然。

二.在哪找人脸的Haar特征分类器

OpenCV有已经自带了人脸的Haar特征分类器。OpenCV安装目录中的data haarcascades目录下的haarcascade_frontalface_alt.xml与haarcascade_frontalface_alt2.xml都是用来检测人脸的Haar分类器。这个haarcascades目录下还有人的全身,眼睛,嘴唇的Haar分类器。读者可以仿照本方的例子来试验下效果看看。

 

物体识别的原理

一般来说,比如想要机器学习着去识别“人脸”,就会使用大量的样本图片来事先培训,这些图片分为两大类,positive和negative的,也就是分为包“含有人脸”的图片和“不包含人脸”的图片,这样当使用程序去一张一张的分析这些图片,然后分析判断并对这些图片“分类” ,即合格的图片与不合格的图片,这也就其为什么叫做 classifier , 这样学习过程中积累的"知识",比如一些判断时的到底临界值多少才能判断是positive还是negative什么的,都会存储在一个个XML文件中,这样使用这些前人经验(这里我们使用了 哈尔 分类器)来对新的图片进行‘专家判断'分析,是否是人脸或者不是人脸。

1.2.3 The cv::CascadeClassifer object

cascade分类器在opencv中作为一个对象,即cv::CascadeClassifer。

图片 16

CascadeClassifer

这个构造函数只有一个参数,即你存储的cascade的文件,如果你想要稍后加载,也可以用load函数。

三.怎么用人脸的Haar特征分类器

使用人脸的Haar特征分类器非常之简单,直接使用cvHaarDetectObjects。下面来看看这个函数的介绍:

函数功能:检测图像中的目录

函数原型:

CVAPI(CvSeq*) cvHaarDetectObjects(

  const CvArr* image,

  CvHaarClassifierCascade* cascade,

  CvMemStorage* storage,

  double scale_factor CV_DEFAULT(1.1),

  int min_neighbors CV_DEFAULT(3),

  int flags CV_DEFAULT(0),

  CvSize min_size CV_DEFAULT(cvSize(0,0)),

  CvSize max_size CV_DEFAULT(cvSize(0,0))

);

函数说明:

第一个参数表示输入图像,尽量使用灰度图以加快检测速度。

第二个参数表示Haar特征分类器,可以用cvLoad()函数来从磁盘中加载xml文件作为Haar特征分类器。

第三个参数为CvMemStorage类型,大家应该很熟悉这个CvMemStorage类型了,《OpenCV入门指南》中很多文章都介绍过了。

第四个参数表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%

Cascade

这里的 Cascade是 层级分类器 的意思。为什么要 分层 呢?刚才提到在进行机器分析照片时,其实是对整个图片从上到下,从左到右,一个像素一个像素的分析,这些分析又会涉及很多的 特征分析 ,比如对于人脸分析就包含识别眼睛,嘴巴等等,一般为了提高分析的准确度都需要有成千上万个特征,这样对于每个像素要进行成千上万的分析,对于整个图片都是百万甚至千万像素,这样总体的计算量会是个天文数字。但是,科学家很聪明,就想到分级的理念,即把这些特征分层,这样分层次去验证图片,如果前面层次的特征没有通过,对于这个图片就不用判断后面的特征了。这有点像是系统架构中的 FF (Fail Fast),这样就提高了处理的速度与效率。

objImage=cv2.imread(inputImageFile)
  • 使用OpenCV库来加载我们传入的测试图片
cvtImage=cv2.cvtColor(objImage,cv2.COLOR_BGR2GRAY)
  • 首先将图片进行灰度化处理,以便于进行图片分析。这种方法在图像识别领域非常常见,比如在进行验证码的机器识别时就会先灰度化,去除不相关的背景噪音图像,然后再分析每个像素,以便抽取出真实的数据。不对针对此,你就看到非常多的验证码后面特意添加了很多的噪音点,线,就是为了防止这种程序来灰度化图片进行分析破解。
foundFaces=faceClassifier.detectMultiScale(cvtImage,scaleFactor=1.3,minNeighbors=9,minSize=,flags = cv2.cv.CV_HAAR_SCALE_IMAGE)
  • 执行detectMultiScale方法来识别物体,因为我们这里使用的是人脸的cascade classifier分类器,因此调用这个方法会来进行面部识别。后面这几个参数来设置进行识别时的配置,比如
  • scaleFactor: 因为在拍照,尤其现在很多都是自拍,这样照片中有的人脸大一些因为离镜头近,而有些离镜头远就会小一些,因为这个参数用于设置这个因素,如果你在使用不同的照片时如果人脸远近不同,就可以修改此参数,请注意此参数必须要大于1.0
  • minNeighbors: 因为在识别物体时是使用一个移动的小窗口来逐步判断的,这个参数就是决定是不是确定找到物体之前需要判断多少个周边的物体
  • minSize:刚才提到识别物体时是合作小窗口来逐步判断的,这个参数就是设置这个小窗口的大小
print(" 在图片中找到了 {} 个人脸".format(len(foundFaces)))
  • 显示出查找到多少张人脸,需要提到的识别物体的方法返回的一个找到的物体的位置信息的列表,因此使用 len 来打印出找到了多少物体。
for  in foundFaces: cv2.rectangle(objImage,,,,2)
  • 遍历发现的“人脸”,需要说明的返回的是由4部分组成的位置数据,即这个“人脸”的横轴,纵轴坐标,宽度与高度。
  • 然后使用 OpenCV 提供的方法在原始图片上画出个矩形。其中 是使用的颜色,这里使用的是R/G/B的颜色表示方法,比如 表示黑色,(255,255,255)表示白色,有些网页编程经验的程序员应该不陌生。
cv2.imshow(u'面部识别的结果已经高度框出来了。按任意键退出'.encode, objImage)cv2.waitKey
  • 接下来是使用 opencv 提供的imshow方法来显示这个图片,其中包括我们刚刚画的红色的识别的结果
  • 最后一个语句是让用户按下键盘任意一个键来退出此图片显示窗口

好了,上面是这个程序的详细解释以及相关的知识的讲解。其实这个只是个抛砖引玉的作用,还用非常多的应用场景,比如程序解析网页上的图片验证码,雅虎前几个月开源的 NSFW, Not Suitable for Work ,即判断那些不适合工作场所的图片,内容你懂的。 :-)

最后,再提一下,所有这些源代码及相关文件都开源在 ,在fork并下载到本地后执行下面代码来测试运行

git clone https://github.com/CloudsDocker/pyFacialRecognition.gitcd pyFacialRecognition./run.sh

如果有任何建议或者想法,请联系我。

  • phray.zhang@gmail.com (email/邮件,whatsapp, linkedin)
  • 微博: cloudsdocker
  • github
  • [简书 jianshu](
  • OpenCV

  • HAAR 哈尔特征

  • Face Detection using Haar Cascades

  • NSFW

1.2.4 Searching an image with detectMultiScale()

实现cascade分类的函数是cv::CascadeClassifer对象中的detectMultiScale()方法。

图片 17

首先输入类型为CV_8U的灰度图片,然后该函数浏览输入图片的所有尺度定位目标并返回到objects参数中,设置scaleFactor决定尺度间的宽度,越大表明计算速度的提高,但可能会丢失目标,minNeighbors参数是对错误判断的控制,因为好的目标检测会在相邻空间碰撞因为周边的像素会暗示该目标的存在。
未完待续。。。

第五个参数表示构成检测目标的相邻矩形的最小个数(默认为3个)。如果组成检测目标的小矩形的个数和小于 min_neighbors

1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上。

第六个参数要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域。

第七个,第八个参数表示检测窗口的最小值和最大值,一般设置为默认即可。

函数返回值:

函数将返回CvSeq对象,该对象包含一系列CvRect表示检测到的人脸矩形。

 

四.人脸识别示例代码

下面给出一个完整的示例代码,代码中的GetTickCount可以参阅《Windows 各种计时函数总结》,cvEqualizeHist可以参阅《【OpenCV入门指南】第八篇灰度直方图》。

[cpp] view plaincopy

 

  1. <pre class="cpp" name="code">// 编译前请配置好VS2008的编译环境  
  2. // 详见《【OpenCV入门指南】第一篇 安装OpenCV》  
  3. // 地址:   
  4.   
  5. // 本文配套博客文章地址:  
  6. //   
  7.   
  8. // Haar特征检测 - 人脸识别  
  9. //By MoreWindows ()  
  10. #include <opencv2/opencv.hpp>  
  11. #include <cstdio>  
  12. #include <cstdlib>  
  13. #include <Windows.h>  
  14. using namespace std;  
  15. int main()  
  16. {  
  17.     // 加载Haar特征检测分类器  
  18.     // haarcascade_frontalface_alt.xml系OpenCV自带的分类器 下面是我机器上的文件路径  
  19.     const char *pstrCascadeFileName = "G:\OpenCV\opencv\data\haarcascades\haarcascade_frontalface_alt.xml";  
  20.     CvHaarClassifierCascade *pHaarCascade = NULL;  
  21.     pHaarCascade = (CvHaarClassifierCascade*)cvLoad(pstrCascadeFileName);  
  22.   
  23.     // 载入图像  
  24.     const char *pstrImageName = "101.jpg";  
  25.     IplImage *pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);  
  26.       
  27.     IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  
  28.     cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);  
  29.   
  30.     // 人脸识别与标记  
  31.     if (pHaarCascade != NULL)  
  32.     {         
  33.         CvScalar FaceCirclecolors[] =   
  34.         {  
  35.             {{0, 0, 255}},  
  36.             {{0, 128, 255}},  
  37.             {{0, 255, 255}},  
  38.             {{0, 255, 0}},  
  39.             {{255, 128, 0}},  
  40.             {{255, 255, 0}},  
  41.             {{255, 0, 0}},  
  42.             {{255, 0, 255}}  
  43.         };  
  44.   
  45.         CvMemStorage *pcvMStorage = cvCreateMemStorage(0);  
  46.         cvClearMemStorage(pcvMStorage);  
  47.         // 识别  
  48.         DWORD dwTimeBegin, dwTimeEnd;  
  49.         dwTimeBegin = GetTickCount();  
  50.         CvSeq *pcvSeqFaces = cvHaarDetectObjects(pGrayImage, pHaarCascade, pcvMStorage);  
  51.         dwTimeEnd = GetTickCount();  
  52.   
  53.         printf("人脸个数: %d   识别用时: %d msn", pcvSeqFaces->total, dwTimeEnd - dwTimeBegin);  
  54.           
  55.         // 标记  
  56.         for(int i = 0; i <pcvSeqFaces->total; i )  
  57.         {  
  58.             CvRect* r = (CvRect*)cvGetSeqElem(pcvSeqFaces, i);  
  59.             CvPoint center;  
  60.             int radius;  
  61.             center.x = cvRound((r->x   r->width * 0.5));  
  62.             center.y = cvRound((r->y   r->height * 0.5));  
  63.             radius = cvRound((r->width   r->height) * 0.25);  
  64.             cvCircle(pSrcImage, center, radius, FaceCirclecolors[i % 8], 2);  
  65.         }  
  66.         cvReleaseMemStorage(&pcvMStorage);  
  67.     }  
  68.       
  69.     const char *pstrWindowsTitle = "人脸识别 ()";  
  70.     cvNamedWindow(pstrWindowsTitle, CV_WINDOW_AUTOSIZE);  
  71.     cvShowImage(pstrWindowsTitle, pSrcImage);  
  72.   
  73.     cvWaitKey(0);  
  74.   
  75.     cvDestroyWindow(pstrWindowsTitle);  
  76.     cvReleaseImage(&pSrcImage);   
  77.     cvReleaseImage(&pGrayImage);  
  78.     return 0;  
  79. }</pre><br>  

五.人脸识别程序运行结果

运行结果一(单人正面):

图片 18

 

这张图的干扰太少,换张干扰大点的图来试试。

 

运行结果二(单人侧面):

图片 19

呵呵,左边那个人眼睛被挡住了,因此普通的人脸检测肯定难以识别的。

 

运行结果三(多人):

图片 20

效果还不错。当然商业级产品的准确度,性能,效率肯定会比OpenCV自带的分类器高的多。

 

下一篇《【OpenCV入门指南】第十四篇  Haartraining》将介绍如何训练Haar特征分类器并简要介绍Haar特征检测的原理。欢迎继续浏览。

 

下面列出OpenCV入门指南系列目录,以方便大家查看:

1.《【OpenCV入门指南】第一篇安装OpenCV》

2.《【OpenCV入门指南】第二篇缩放图像》

3.《【OpenCV入门指南】第三篇Canny边缘检测》

4.《【OpenCV入门指南】第四篇图像的二值化》

5.《【OpenCV入门指南】第五篇轮廓检测上》

6.《【OpenCV入门指南】第六篇轮廓检测下》

7.《【OpenCV入门指南】第七篇线段检测与圆检测》

8.《【OpenCV入门指南】第八篇灰度直方图》

9.《【OpenCV入门指南】第九篇灰度直方图均衡化》

10.《【OpenCV入门指南】第十篇彩色直方图均衡化》

11.《【OpenCV入门指南】第十一篇鼠标绘图》

12.《【OpenCV入门指南】第十二篇无法运行OpenCV程序?》

13.《【OpenCV入门指南】第十三篇人脸识别》

14.《【OpenCV入门指南】第十四篇  Haartraining》即将发布

 

 

 

 

 

《OpenCV入门指南》系列文章地址:

转载请标明出处,原文地址:

本文由新葡京8455发布,转载请注明来源

关键词: