OpenCV使用Python进行人脸检测

本文概述

  • 介绍
  • 先决条件
  • 目录
  • 总览
  • 安装
  • 1.二进制图像
  • 2.灰度图像
  • 3.彩色图像
  • 在OpenCV中导入图像
  • 节省影像
  • 图像的基本操作
  • 总览
  • 基于Haar特征的级联分类器
  • 使用OpenCV-Python进行人脸检测
介绍 人脸检测是一种计算机视觉技术, 可帮助定位/可视化数字图像中的人脸。该技术是对象检测技术的一个特定用例, 它用于检测数字图像和视频中特定类别的语义对象(例如人, 建筑物或汽车)的实例。随着技术的出现, 人脸检测已经变得越来越重要, 尤其是在摄影, 安全和市场营销等领域。
先决条件 在研究OpenCV概念之前, 必须具备Numpy和Matplotlib的动手知识。在安装OpenCV之前, 请确保已安装并运行以下软件包。
  • python
  • 麻木
  • matplotlib
目录 OpenCV的Python
  • 1.概述
  • 2.安装
图像作为数组
  • 二进制图像
  • 灰度图像
  • 彩色图像
图片和OpenCV
  • 在OpenCV中导入图像
  • 节省影像
  • 图像的基本操作
人脸检测
  • 总览
  • 基于Haar特征的级联分类器
  • 使用OpenCV-Python进行人脸检测
总结 总览
OpenCV使用Python进行人脸检测

文章图片
OpenCV由Gary Bradsky于1999年在英特尔创立。第一个发行版于2000年晚些时候发布。OpenCV本质上是开源计算机视觉库的缩写。尽管它是用优化的C / C ++编写的, 但它具有适用于Python和Java以及C ++的接口。 OpenCV在全球拥有活跃的用户群, 由于计算机视觉应用的激增, 其使用量每天都在增加。
OpenCV-Python是OpenCV的python API。你可以将其视为围绕OpenCV的C ++实现的python包装器。 OpenCV-Python不仅速度快(因为背景由用C / C ++编写的代码组成), 而且易于编码和部署(由于前景中使用了Python包装器)。这使其成为执行计算密集型程序的绝佳选择。
安装 OpenCV-Python支持所有领先的平台, 例如Mac OS, Linux和Windows。可以通过以下两种方式之一进行安装:
1.从预编译的二进制文件和来源:
请参阅此处的Windows和Mac的详细文档。
2.用于Python的非官方的预构建OpenCV软件包。
适用于标准桌面环境的软件包(Windows, macOS, 几乎所有GNU / Linux发行版)
  • 如果只需要主要模块, 请运行pip install opencv-python
  • 如果需要主模块和contrib模块, 请运行pip install opencv-contrib-python(请参阅OpenCV文档中列出的其他模块)
你可以使用Jupyter笔记本或你选择的任何Python IDE编写脚本。
图像不过是包含数据点像素的标准Numpy数组。图像中的像素数越多, 其分辨率越好。你可以将像素视为以二维栅格形式排列的微小信息块, 而像素的深度是指其中存在的颜色信息。为了由计算机处理, 图像需要转换为二进制形式。图像的颜色可以如下计算:
Number of colors/ shades = 2^bpp where bpp represents bits per pixel.

自然地, 位数/像素越多, 图像中可能的颜色就越多。下表更清楚地显示了这种关系。
OpenCV使用Python进行人脸检测

文章图片
现在让我们看一下不同类型图像的表示:
1.二进制图像 二进制图像由1位/像素组成, 因此只能具有两种可能的颜色, 即黑色或白色。黑色由值0表示, 而1表示白色。
OpenCV使用Python进行人脸检测

文章图片
2.灰度图像 灰度图像由每个像素8位组成。这意味着它可以具有256种不同的阴影, 其中0像素表示黑色, 而255表示白色。例如, 下图显示了以阵列形式表示的灰度图像。灰度图像只有1个通道, 其中通道代表尺寸。
OpenCV使用Python进行人脸检测

文章图片
3.彩色图像 彩色图像表示为红色, 蓝色和绿色的组合, 并且可以通过以正确的比例混合这些原色来获得所有其他颜色。
OpenCV使用Python进行人脸检测

文章图片
资源
彩色图像还包括每个像素8位。结果, 可以用0表示黑色和255白色表示256种不同的颜色阴影。让我们看一下在许多图像处理示例中都引用的著名的山d彩色图像。
OpenCV使用Python进行人脸检测

文章图片
如果我们检查上面图像的形状, 我们将得到:
Shape (288, 288, 3) 288: Pixel width 288: Pixel height 3: color channel

这意味着我们可以以三维数组的形式表示上面的图像。
OpenCV使用Python进行人脸检测

文章图片
在我们开始人脸检测之前, 让我们学习一些使用OpenCV的基础知识。在本节中, 我们将使用OpenCV对图像执行简单的操作, 例如打开图像, 在图像上绘制简单的形状以及通过回调与图像进行交互。这是建立基础的必要条件, 然后再转向高级课程。
在OpenCV中导入图像 使用Jupyter笔记本
步骤如下:
  • 导入必要的库
import numpy as np import cv2 import matplotlib.pyplot as plt %matplotlib inline

  • 使用imread功能读入图像。我们将使用彩色的” 山d” 图像进行演示。可以从这里下载
img_raw = cv2.imread('image.jpg')

  • 数组的类型和形状。
type(img_raw) numpy.ndarrayimg_raw.shape (1300, 1950, 3)

因此, .png图像将转换为形状为1300× 1950的numpy数组, 并具有3个通道。
  • 查看图像
plt.imshow(img_raw)

OpenCV使用Python进行人脸检测

文章图片
我们得到的输出在颜色方面有些不同。我们期望得到色彩鲜艳的图像, 但获得的是带有淡蓝色调的图像。发生这种情况是因为OpenCV和matplotlib具有不同顺序的原色。 OpenCV读取BGR格式的图像, 而matplotlib则遵循RGB的顺序。因此, 当我们通过OpenCV读取文件时, 我们将其读取为包含蓝色, 绿色和红色顺序的通道。但是, 当我们使用matplotlib显示图像时, 红色和蓝色通道被交换, 因此蓝色调。为避免此问题, 我们将通道转换为matplotlib期望使用cvtColor函数的方式。
img = cv2.cvtColor(img_raw, cv2.COLOR_BGR2RGB) plt.imshow(img_rgb)

OpenCV使用Python进行人脸检测

文章图片
使用Python脚本
Jupyter笔记本非常适合学习, 但是在处理复杂的图像和视频时, 我们需要在单独的窗口中显示它们。在本节中, 我们将代码作为.py文件执行。你可以使用Pycharm, Sublime或你选择的任何IDE来运行以下脚本。
import cv2 img = cv2.imread('image.jpg') while True: cv2.imshow('mandrill', img)if cv2.waitKey(1) & 0xFF == 27: breakcv2.destroyAllWindows()

在此代码中, 我们有一个条件, 并且只有在条件为true时才会显示图像。另外, 要打破循环, 我们要满足两个条件:
  • cv2.waitKey()是键盘绑定函数。它的参数是以毫秒为单位的时间。该函数等待任何键盘事件的指定毫秒数。如果在此期间按任意键, 程序将继续。
  • 第二个条件与按下键盘上的Escape键有关。因此, 如果经过了1毫秒并按下了退出键, 则循环将中断并且程序将停止。
  • cv2.destroyAllWindows()只会破坏我们创建的所有窗口。如果要销毁任何特定的窗口, 请使用函数cv2.destroyWindow()在其中传递确切的窗口名称作为参数。
节省影像 可以将图像保存在工作目录中, 如下所示:
cv2.imwrite('final_image.png', img)

其中final_image是要保存的图像的名称。
图像的基本操作 在本节中, 我们将学习如何在现有图像上绘制各种形状, 从而获得使用OpenCV的感觉。
在图像上绘图
  • 首先导入必要的库。
import numpy as np import matplotlib.pyplot as plt %matplotlib inline import cv2

  • 创建将用作模板的黑色图像。
image_blank = np.zeros(shape=(512, 512, 3), dtype=np.int16)

  • 显示黑色图像。
plt.imshow(image_blank)

OpenCV使用Python进行人脸检测

文章图片
功能和属性
用于在图像上绘制形状的通用功能是:
cv2.shape(line, rectangle etc)(image, Pt1, Pt2, color, thickness)

在函数中传递了一些常见的参数以在图像上绘制形状:
  • 要在其上绘制形状的图像
  • 从Pt1(左上)到Pt2(右下)绘制的形状的坐标
  • 颜色:要绘制的形状的颜色。它作为元组传递, 例如:(255, 0, 0)。对于灰度, 它将是亮度的比例。
  • 几何图形的厚度。
1.直线 在图像上绘制一条直线需要指定直线穿过的点。
# Draw a diagonal red line with thickness of 5 px line_red = cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 5) plt.imshow(line_red)

OpenCV使用Python进行人脸检测

文章图片
# Draw a diagonal green line with thickness of 5 px line_green = cv2.line(img, (0, 0), (511, 511), (0, 255, 0), 5) plt.imshow(line_green)

OpenCV使用Python进行人脸检测

文章图片
2.矩形 对于矩形, 我们需要指定左上角和右下角坐标。
#Draw a blue rectangle with a thickness of 5 pxrectangle= cv2.rectangle(img, (384, 0), (510, 128), (0, 0, 255), 5) plt.imshow(rectangle)

OpenCV使用Python进行人脸检测

文章图片
3.圈 对于圆, 我们需要传递其中心坐标和半径值。让我们在上面绘制的矩形内绘制一个圆
img = cv2.circle(img, (447, 63), 63, (0, 0, 255), -1) # -1 corresponds to a filled circle plt.imshow(circle)

OpenCV使用Python进行人脸检测

文章图片
在图像上书写
向图像添加文本也类似于在图像上绘制形状。但是你需要先指定某些参数, 然后再执行以下操作:
  • 要写的文字
  • 文本的坐标。图像上的文字从左下方开始。
  • 字体类型和比例。
  • 其他属性, 例如颜色, 粗细和线型。通常, 使用的线型是lineType = cv2.LINE_AA。
font = cv2.FONT_HERSHEY_SIMPLEX text = cv2.putText(img, 'OpenCV', (10, 500), font, 4, (255, 255, 255), 2, cv2.LINE_AA) plt.imshow(text)

OpenCV使用Python进行人脸检测

文章图片
这些是可以使用OpenCV在图像上完成的较小操作。随意尝试形状和文字。
总览 人脸检测是一种在数字图像中识别或定位人脸的技术。当我们通过智能手机拍摄照片时, 就会出现人脸检测的典型示例, 它会立即检测到照片中的人脸。人脸检测与人脸识别不同。人脸检测仅检测图像中人脸的存在, 而人脸识别则涉及识别人脸。在本文中, 我们仅涉及前者。
通过使用分类器执行面部检测。分类器本质上是一种算法, 用于确定给定图像是正(脸)还是负(不是脸)。分类器需要在具有和没有面孔的数千张图像上进行训练。幸运的是, OpenCV已经具有两个经过预先训练的面部检测分类器, 可以在程序中轻松使用。这两个分类器是:
  • 她的分类器和
  • 本地二进制模式(LBP)分类器。
但是, 在本文中, 我们将仅讨论Haar分类器。
基于Haar特征的级联分类器 类Haar的特征是用于对象识别的数字图像特征。他们的名字得益于其与Haar小波的直观相似性, 并被用于首个实时面部检测器中。保罗·维奥拉(Paul Viola)和迈克尔·琼斯(Michael Jones)在他们的论文《使用简单特征的增强级联进行快速物体检测》中使用了基于Haar小波的Haar特征分类器的思想。该分类器广泛用于计算机视觉行业中的人脸检测等任务。
Haar级联分类器采用机器学习方法进行视觉对象检测, 该方法能够极其快速地处理图像并实现高检测率。这可以归因于三个主要原因:
  • Haar分类器采用” 积分图像” 概念, 可以非常快速地计算出探测器使用的特征。
  • 学习算法基于AdaBoost。它从大量集中选择少量重要特征, 并提供高效的分类器。
  • 更复杂的分类器组合在一起形成” 级联” , 该级联会丢弃图像中的任何非面部区域, 从而将更多的计算花费在有前途的类似对象的区域上。
现在让我们尝试并逐步了解该算法如何处理图像:
1.” 其特征” 提取
在将大量训练数据(以图像的形式)输入系统后, 分类器首先从每个图像中提取Haar特征。 Haar特征是一种卷积核, 主要检测图像上是否存在合适的特征。下面提到了Haar功能的一些示例:
OpenCV使用Python进行人脸检测

文章图片
资源
这些Haar功能就像窗口一样, 放置在图像上以计算单个功能。该特征本质上是通过减去白色区域下的像素和黑色区域下的像素之和获得的单个值。在下面的示例中可以很容易地看到该过程。
OpenCV使用Python进行人脸检测

文章图片
出于演示目的, 假设我们仅提取两个功能, 因此这里只有两个窗口。第一个特征在于眼睛区域比相邻的脸颊和鼻子区域更暗。第二个特征着眼于与鼻梁相比, 眼睛较暗的事实。因此, 当特征窗口移到眼睛上方时, 它将计算单个值。然后将该值与某个阈值进行比较, 如果超过该阈值, 将得出结论, 此处存在边缘或某些正特征。
2.” 整体形象” 的概念
Viola Jones提出的算法使用24X24的基本窗口大小, 这将导致在此窗口中计算出180, 000多个特征。想象一下计算所有功能的像素差吗?为此计算密集型过程设计的解决方案是采用” 积分图像” 概念。积分图像意味着要找到任何矩形下所有像素的总和, 我们只需要四个角值即可。
OpenCV使用Python进行人脸检测

文章图片
资源
这意味着, 要计算任何特征窗口中的像素总和, 我们不需要将它们单独求和。我们需要的是使用4个角值计算积分图像。下面的示例将使过程透明。
OpenCV使用Python进行人脸检测

文章图片
资源
3.’ Adaboost’ :提高分类器准确性
如上所述, 在24X24的窗口内会产生180, 000多个特征值。但是, 并非所有功能都可用于识别人脸。为了仅从整个块中选择最佳功能, 使用了一种称为Adaboost的机器学习算法。它的本质作用是仅选择有助于提高分类器准确性的那些功能。它通过构造一个强分类器来实现, 该分类器是许多弱分类器的线性组合。这将功能数量从大约180, 000大幅减少到大约6000。
4.使用” 级联分类器”
Viola Jones确保算法快速执行的另一种方法是采用级联分类器。级联分类器实质上由多个阶段组成, 其中每个阶段均由一个强分类器组成。这是有益的, 因为它消除了一次在窗口上应用所有功能的需求。而是将特征分组到单独的子窗口中, 并且在每个阶段, 分类器确定子窗口是否为人脸。如果不是, 子窗口将与该窗口中的功能一起丢弃。如果子窗口移过分类器, 它将继续到下一个阶段, 其中应用第二阶段的功能。可以借助下图了解该过程。
OpenCV使用Python进行人脸检测

文章图片
Haar分类器的级联结构。
Paul-Viola算法可以如下所示:
OpenCV使用Python进行人脸检测

文章图片
资源
使用OpenCV-Python进行人脸检测 现在我们对面部识别背后的直觉和过程有了一个清晰的认识。现在让我们使用OpenCV库检测图像中的人脸。
加载必要的库
import numpy as np import cv2 import matplotlib.pyplot as plt %matplotlib inline

以灰度加载要测试的图像
我们将使用以下图像:
OpenCV使用Python进行人脸检测

文章图片
#Loading the image to be tested test_image = cv2.imread('data/baby1.jpg')#Converting to grayscale test_image_gray = cv2.cvtColor(test_image, cv2.COLOR_BGR2GRAY)# Displaying the grayscale image plt.imshow(test_image_gray, cmap='gray') Since we know that OpenCV loads an image in BGR format, so we need to convert it into RBG format to be able to display its true colors. Let us write a small function for that.

OpenCV使用Python进行人脸检测

文章图片
【OpenCV使用Python进行人脸检测】由于我们知道OpenCV以BGR格式加载图像, 因此我们需要将其转换为RBG格式才能显示其真实颜色。让我们为此编写一个小函数。
def convertToRGB(image): return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

她的级联文件
OpenCV附带了许多预先训练的分类器。例如, 存在用于微笑, 眼睛, 面部等的分类器。这些分类器以xml文件的形式出现, 位于opencv / data / haarcascades /文件夹中。但是, 为简化起见, 你也可以从此处访问它们。下载xml文件, 并将其放置在与jupyter笔记本电脑相同的工作目录中的data文件夹中。
加载正面的分类器
haar_cascade_face = cv2.CascadeClassifier('data/haarcascade/haarcascade_frontalface_default.xml')

人脸检测
我们将使用分类器的detectMultiscale模块。此函数将返回围绕检测到的脸部的坐标为(x, y, w, h)的矩形。此功能有两个重要参数, 必须根据数据进行调整。
  • 比例系数在集体照片中, 可能有一些人的脸比其他人的更靠近相机。自然, 这样的面孔会比后面的面孔更为突出。这个因素弥补了这一点。
  • minNeighbors此??参数指定必须将矩形称为面的邻居数。你可以在这里读更多关于它的内容。
faces_rects = haar_cascade_face.detectMultiScale(test_image_gray, scaleFactor = 1.2, minNeighbors = 5); # Let us print the no. of faces found print('Faces found: ', len(faces_rects))Faces found:1

下一步是遍历返回的所有坐标, 并使用Open CV在其周围绘制矩形。我们将绘制一个厚度为2的绿色矩形
for (x, y, w, h) in faces_rects: cv2.rectangle(test_image, (x, y), (x+w, y+h), (0, 255, 0), 2)

最后, 我们将用彩色显示原始图像, 以查看是否已正确检测到脸部。
#convert image to RGB and show imageplt.imshow(convertToRGB(test_image))

OpenCV使用Python进行人脸检测

文章图片
这里是。我们已成功检测出图片中婴儿的脸。现在让我们为整个面部检测过程创建一个通用函数。
具有通用功能的人脸检测
def detect_faces(cascade, test_image, scaleFactor = 1.1): # create a copy of the image to prevent any changes to the original one. image_copy = test_image.copy()#convert the test image to gray scale as opencv face detector expects gray images gray_image = cv2.cvtColor(image_copy, cv2.COLOR_BGR2GRAY)# Applying the haar classifier to detect faces faces_rect = cascade.detectMultiScale(gray_image, scaleFactor=scaleFactor, minNeighbors=5)for (x, y, w, h) in faces_rect: cv2.rectangle(image_copy, (x, y), (x+w, y+h), (0, 255, 0), 15)return image_copy

测试新图像上的功能
这次的测试图像如下:
OpenCV使用Python进行人脸检测

文章图片
#loading image test_image2 = cv2.imread('baby2.jpg')# Converting to grayscale test_image_gray = cv2.cvtColor(test_image, cv2.COLOR_BGR2GRAY)# Displaying grayscale image plt.imshow(test_image_gray, cmap='gray')

OpenCV使用Python进行人脸检测

文章图片
#call the function to detect faces faces = detect_faces(haar_face_cascade, test_image2) #convert to RGB and display image plt.imshow(convertToRGB(faces))

OpenCV使用Python进行人脸检测

文章图片
测试组图像上的功能
现在让我们看看该功能在集体照上是否运作良好。我们将使用以下图片作为我们的目的。
OpenCV使用Python进行人脸检测

文章图片
图片:印度女子板球队。
#loading image test_image2 = cv2.imread('group.jpg')#call the function to detect faces faces = detect_faces(haar_cascade_face, test_image2)#convert to RGB and display image plt.imshow(convertToRGB(faces))

OpenCV使用Python进行人脸检测

文章图片
你可以从此处下载整个源代码。
在本教程中, 我们了解了使用Haar级联在Python中使用Open CV进行面部检测的概念。在库中可以找到除面部以外的许多检测器。随时进行实验, 并创建用于眼睛, 车牌等的探测器。如有任何疑问, 请在下面留下评论。

    推荐阅读