---
title: '在Python中使用OpenCV进行人脸检测'
pubDate: 2018-05-12
tags:
  - 'cv'
description: '在Python中使用OpenCV进行人脸检测'
---

**_OpenCV是如今最流行的计算机视觉库，而我们今天就是要学习如何安装使用OpenCV，以及如何去访问我们的摄像头。然后我们一起来看看写一个人脸检测程序是如何地简单，简单到只需要几行代码。_**

在开始之前，我假设你已经对Python有一定的了解。当然，如果你觉得你还不够格，这里有推荐一些[学习Python的电子书](https://amzn.to/2kUK9WQ)，你可以先学习下Python，如此可以让你更好地理解接下来的步骤。另外，这里还推荐一本[电子书](https://amzn.to/2mtfCf1)来学习OpenCV。

好，不浪费时间，开始吧。

首先我们需要先准备好这些环境（版本记得配好）：

- Python 2.x
- OpenCV 2.x
- Numpy库 (这个可以在稍后用pip下载)

首先，对于下载Python，我们可以先到[官网](https://www.python.org/downloads/)上下对应的版本，如果是Windows就可能是msi格式的版本，如果是Mac就可能是pkg格式的安装包，如果是Linux则可能是源码包。

安装和Python后打开命令行就可以使用pip命令进行Python包的安装了，如：

![](https://source.mkshell.com/15261274043025.jpg)

由于OpenCV使用Numpy库，因此先通过命令`pip install numpy`安装Numpy库。安装完后，尝试导入，没有报错则ok：

![](https://source.mkshell.com/15261275174355.jpg)

然后进入[OpenCV官网](https://opencv.org/releases.html)下对应的版本并安装，尝试导入：

![](https://source.mkshell.com/15261276882488.jpg)

## 尝试人脸检测

万事俱备，只欠东风。我们来写代码检测人脸吧，来一发OpenCV的Hello world。

在这里我们准备使用pre-trained的XML文件，这些XML文件都较难训练，但是我们不需要担心，因此OpenCV已经为我们提供了很多人脸检测相关的pre-trained分类器。

想要使用这写分类器，我们需要将分类器的XML文件`haarcascade_frontalface_default.xml`从`opencv文件夹/sources/data/haarcascades/`下复制到我们的项目目录下，就是我们将要写程序的目录下。如果没有`opencv文件夹/sources/data/haarcascades/`这个目录，可以尝试找一下`opencv文件夹/share/OpenCV/haarcascades/`。只要找到如下文件即可：

![](https://source.mkshell.com/15261284236153.jpg)

然后如果我们要加载这个分类器的话，如此就好：

```
detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
```

然后接下来我们先来测试一下摄像头吧，

```
cap = cv2.VideoCapture(0)
ret, img = cap.read()
cv2.imshow('windowname', img)
cv2.waitKey(0)

# 释放摄像头资源
cap.release()
```

以上的代码是调用你电脑的0号摄像头，并展示出来。当然，如果你有多个摄像头，那么你也可以试试别的id，修改VideoCapture函数的参数即可。

其中cap.read()就是从摄像头获取到图像，这个函数返回了两个变量，第一个为布尔值表示成功与否，以及第二个是图像。

然后程序通过imshow()展示图片，其第一个传入的参数为窗口的名称，而第二个就是要展示的图片，以上代码传入的就是我们的自拍。

而waitKey是用来停在图片的展示界面，让你看清楚，参数可以是10、100、1000等，单位是毫秒，这里填0就是一直停着。注意了，如果停留的时间不够久，就可能看不见imshow的照片了。

运行了这段代码，你将会看到摄像头所拍摄的画面，一般来说就是你自己了。

![](https://source.mkshell.com/15261313899799.jpg)

接下来我们将图片先转换为灰度图片，

```
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
```

然后就开始了人脸检测之旅：

```
faces = detector.detectMultiScale(gray, 1.3, 5)
```

以上的这句代码会等到一串list，list中的每个都有x, y, height, width四个变量。其中list表示检测到的人脸，即list的size就是人脸的个数，而每个人脸在图片中的位置是（x, y, height, width）。

为了能让我们更直观地看出来检测结果，我们将这些人脸框出来：

```
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
```

![](https://source.mkshell.com/15261316384652.jpg)

## 更进一步

现在我们已经通过摄像头检测到人脸了，但是我们真正需要的是不是一张静态的图片，我们需要的是一个能检测的实时动态视频流。因此我们加一个循环，然后不断的检测，最终在显示在新窗口中。

```
detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

    cv2.imshow('frame', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
```

需要注意的是，结尾用了waitKey和ord实现了按q退出的功能，就是每一毫秒都在检测键盘有没有按下了q，要是按下了就退出循环了。接下来就释放资源。

## 总结

在本文中，我们学习了如何使用Python中的OpenCV，即通过代码写了一个人脸检测的程序。我们温习或学习了这些知识点：

- 使用OpenCV的分类器
- 从摄像头中读取照片
- 在图片上换框框
- 在新窗口上展示图片
- 实时地进行人脸检测

**_P.S. 你们发现了XML那里有一个叫猫脸识别的文件吗！！！_**

_先这样吧_

[原文](https://thecodacus.com/opencv-python-face-detection/#.WvbdLtOWT5t)，若有错误之处请指出，更多地关注[煎鱼](http://www.jianyujianyu.com)。
