master
aolingwen 6 years ago
parent 031cf6c181
commit 51fc684d90

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

@ -0,0 +1,170 @@
# 6.2.1 OpenCV入门
## 什么是OpenCV
`OpenCV`是计算机视觉领域应用最广泛的开源工具包,基于`C/C++`,支持`Linux/Windows/MacOS/Android/iOS`,并提供了`PythonMatlab`和`Java`等语言的接口,因为其丰富的接口,优秀的性能和商业友好的使用许可,不管是学术界还是业界中都非常受欢迎。`OpenCV`最早源于`Intel`公司`1998`年的一个研究项目,当时在`Intel`从事计算机视觉的工程师盖瑞·布拉德斯基(`Gary Bradski`)访问一些大学和研究组时发现学生之间实现计算机视觉算法用的都是各自实验室里的内部代码或者库,这样新来实验室的学生就能基于前人写的基本函数快速上手进行研究。于是`OpenCV`旨在提供一个用于计算机视觉的科研和商业应用的高性能通用库。
第一个`alpha`版本的`OpenCV`于`2000`年的`CVPR`上发布在接下来的5年里又陆续发布了`5`个`beta`版本,`2006`年发布了第一个正式版。`2009`年随着盖瑞加入了`Willow Garage``OpenCV`从`Willow Garage`得到了积极的支持,并发布了`1.1`版。`2010`年`OpenCV`发布了`2.0`版本,添加了非常完备的`C++`接口,从`2.0`开始的版本非常用户非常庞大,至今仍在维护和更新。`2015`年`OpenCV 3`正式发布,除了架构的调整,还加入了更多算法,更多性能的优化和更加简洁的`API`,另外也加强了对`GPU`的支持,现在已经在许多研究机构和商业公司中应用开来。
## 安装OpenCV
想要安装`OpenCV`非常简单,只需在有网的环境下,在命令行中输入指令:`pip install opencv-python`即可安装。
安装好后,使用如下代码,若能成功运行,则说明安装成功。
```python
import cv2
print(cv2.__version__)
```
## 读取并显示图片
假设在当前目录有一张图片,图片名为`example.png`,那么可以使用`imread`函数读取图片,使用`namedWindow`函数创建显示图片的窗口,使用`imshow`函数显示图片。
```python
import cv2
# 读取图片
src=cv2.imread('./example.png')
# 创建一个标题为input_image的窗口
cv2.namedWindow('input_image', cv2.WINDOW_AUTOSIZE)
# 在标题为input_image的窗口上显示图片
cv2.imshow('input_image', src)
cv2.waitKey(0)
# 销毁窗口
cv2.destroyAllWindows()
```
![](1.jpg)
## 图像缩放
有的时候,得到的原始图像数据集中的图像大小不一致,如果想要将图像缩放至固定的宽高,则可以使用`resize`函数实现功能。
```python
import cv2
# 读取图片
src=cv2.imread('./example.png')
# 将src图片缩放成宽为64个像素高为64个像素的图像并保存在dst变量中
dst = cv2.resize(src, (246, 256))
# 创建一个标题为input_image的窗口
cv2.namedWindow('input_image', cv2.WINDOW_AUTOSIZE)
# 创建一个标题为resized_image的窗口
cv2.namedWindow('resized_image', cv2.WINDOW_AUTOSIZE)
# 在标题为input_image的窗口上显示图片src
cv2.imshow('input_image', src)
# 在标题为resized_image的窗口上显示图片dst
cv2.imshow('resized_image', dst)
cv2.waitKey(0)
# 销毁窗口
cv2.destroyAllWindows()
```
![](2.jpg)
## 彩色图转灰度图
有的时候颜色信息对于我们的任务来说并不是特别重要,此时可以使用`cvtColor`函数实现将彩色图转换成灰度图。
```python
import cv2
# 读取图片
src=cv2.imread('./example.png')
# 将图片src从BGR的彩色图转换成灰度图并保存到dst
dst = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# 创建一个标题为input_image的窗口
cv2.namedWindow('input_image', cv2.WINDOW_AUTOSIZE)
# 创建一个标题为resized_image的窗口
cv2.namedWindow('gray_image', cv2.WINDOW_AUTOSIZE)
# 在标题为input_image的窗口上显示图片src
cv2.imshow('input_image', src)
# 在标题为resized_image的窗口上显示图片dst
cv2.imshow('gray_image', dst)
cv2.waitKey(0)
# 销毁窗口
cv2.destroyAllWindows()
```
![](3.jpg)
## 二值化
图像二值化就是将图像上的像素点的灰度值设置为`0`或`255`,也就是将整个图像呈现出明显的黑白效果的过程。二值化的原理就是找到一个合适的阈值`t`,然后遍历整张图片中所有的像素点,当像素点的灰度值高于阈值`t`时,将该像素点的灰度值置为`255`,否则置成`0`。`OpenCV`中提供了实现二值化的函数`threshold`。
```python
import cv2
# 读取图片0表示读取到的图片为灰度图
src=cv2.imread('./example.png', 0)
# 对图片scr进行二值化cv2.THRESH_OTSU表示自动找出合适的阈值并将二值化后的图保存到dst
_, dst = cv2.threshold(src, 127, 255, cv2.THRESH_OTSU)
# 创建一个标题为input_image的窗口
cv2.namedWindow('input_image', cv2.WINDOW_AUTOSIZE)
# 创建一个标题为resized_image的窗口
cv2.namedWindow('gray_image', cv2.WINDOW_AUTOSIZE)
# 在标题为input_image的窗口上显示图片src
cv2.imshow('input_image', src)
# 在标题为resized_image的窗口上显示图片dst
cv2.imshow('gray_image', dst)
cv2.waitKey(0)
# 销毁窗口
cv2.destroyAllWindows()
```
![](4.jpg)
## 直方图均衡
对曝光过度或者逆光拍摄的图片可以通过直方图均衡化的方法用来增强局部或者整体的对比度。
具体思路是通过找出图像中最亮和最暗的像素值将之映射到纯黑和纯白之后再将其他的像素值按某种算法映射到纯黑和纯白之间的值。另一种方法是寻找图像中像素的平均值作为中间灰度值,然后扩展范围以达到尽量充满可显示的值。
什么是直方图?你可以把直方图看作一个图或图,它给你一个关于图像的强度分布的总体思路。它是一个带有像素值的图(从`0`到`255`,不总是)在`x`轴上,在`y`轴上的图像对应的像素个数。
这只是理解图像的另一种方式。通过观察图像的直方图,你可以直观地了解图像的对比度、亮度、亮度分布等。今天几乎所有的图像处理工具都提供了直方图上的特征。
![](5.jpg)
你可以看到图像和它的直方图。(这个直方图是用灰度图像绘制的,而不是彩色图像)。直方图的左边部分显示了图像中较暗像素的数量,右边区域显示了更明亮的像素。从直方图中可以看到,深色区域的像素数量比亮色区域更多,而中间色调的数量(中值大约在`127`左右)则少得多。
考虑一个图像,其像素值仅限制在特定的值范围内。例如,更明亮的图像将使所有像素都限制在高值中。但是一个好的图像会有来自图像的所有区域的像素。所以你需要把这个直方图拉伸到两端(如下图所给出的),这就是直方图均衡的作用(用简单的话说)。这通常会改善图像的对比度。
![](6.jpg)
`OpenCV`中提供了实现直方图均衡的函数`equalizeHist`。
```python
import cv2
# 读取图片0表示读取到的图片为灰度图
src=cv2.imread('./example.png', 0)
# 对图片scr进行直方图均衡并将结果保存到dst
dst = cv2.equalizeHist(src)
# 创建一个标题为input_image的窗口
cv2.namedWindow('input_image', cv2.WINDOW_AUTOSIZE)
# 创建一个标题为resized_image的窗口
cv2.namedWindow('equalized_image', cv2.WINDOW_AUTOSIZE)
# 在标题为input_image的窗口上显示图片src
cv2.imshow('input_image', src)
# 在标题为resized_image的窗口上显示图片dst
cv2.imshow('equalized_image', dst)
cv2.waitKey(0)
# 销毁窗口
cv2.destroyAllWindows()
```
![](7.jpg)

@ -0,0 +1,110 @@
# 6.2.2 人脸位置检测
`OpenCV`的人脸检测,使用`Harr分类器`。该分类器采用的`Viola-Jones人脸检测算法`。它是在 `2001`年由`Viola`和`Jones`提出的基于机器学习的人脸检测算法。
算法首先需要大量的积极图片(包含人脸的图片)和消极图片(不包含人脸的图片)。然后从中提取类`Harr特征( Harr-like features)`,之所以称为`Harr`分类器,是正是因为它使用了类`Harr`特征。最后,训练出一个级联检测器,用其来检测人脸。
## 类Harr特征
图像中的特征通常是指,图片的像素点经过一系列的运算之后得到的结果,这些结果可能是向量、矩阵和多维数据等等。类`Harr`特征是一种反映图像的灰度变化的,像素分模块求差值的一种特征。
## Harr特征类别
它分为三类:边缘特征、线性特征、中心特征和对角线特征。用黑色两种矩形框组成为特征模板。
`1`.边缘特征
![](8.jpg)
`2`.线性特征
![](9.jpg)
`3`.中心特征和对角线特征
![](10.jpg)
## 特征值计算
特征模板的特征值计算的方式,是用黑色矩形像素总和的均值减去白色矩形像素总和的均值。
$$ \Delta = \frac{1}{n}\sum_{dark}^{n}I(x)-\frac{1}{n}\sum_{white}^{n}I(x) $$
例如,对于`4x4`的像素块。
理想情况下,黑色和白色的像素块分布如下:
![](11.jpg)
符合边缘特征的情况(`a`)。
但是通常情况,一张灰阶照片的黑白分布并非如此的明显,例如:
![](12.jpg)
根据公式,第一张图特征值为`1`,第二张图特征值为`0.75-0.18=0.56`。
一张图中,对于识别人脸,只有部分特征是有效的。例如,用下图中的特征模板可以看出,眉毛区域比额头要亮,鼻梁区域比眼镜区域要亮。嘴唇区域比牙齿区域要暗。这样的类`Harr`特征能很好的识别出人脸。
![](13.jpg)
为简化特征值计算,可以使用积分图算法。得到类`Harr`特征后,使用`AdaBoost`的方法选择出有效特征。最后再使用瀑布型级联检测器提高检测速度。其中,瀑布的每一层都是一个由`Adaboost算法`训练得到的强分类器。
`Harr`人脸检测一个简单的动画过程如下:
![](14.gif)
红色的搜索框不断移动,检测出是否包含人脸。一般来说,输入的图片会大于样本,为了检索出不同大小的目标,分类器可以按比例的改变自己的尺寸,对输入图片进行多次的扫描。
## 训练Harr分类器
训练`Harr`分类器的主要步骤如下:
- 搜集制作大量的“消极”图像
- 搜集制作大量“积极”图像,确保这些图像中包含要检测的对象
- 创建“积极”向量文件
- 使用`OpenCV`训练`Harr`分类器
因为训练需要花费较多的资源和时间,所以我们学习时,先使用`OpenCV`中已经训练好的`Harr`分类器。
## 使用Harr分类器检测人脸
声明分类器:
CascadeClassifier(模型文件路径)
调用分类函数:
detectMultiScale(图片对象,scaleFactor, minNeighbors, minSize)
参数说明:
1. 图片对象:待识别图片对象;
2. `scaleFactor`:图像缩放比例;
3. `minNeighbors`:对特征检测点周边多少有效点同时检测,这样可避免因选取的特征检测点太小而导致遗漏;
4. `minSize`:特征检测点的最小尺寸,可选参数。
示例如下:
```
import numpy as np
import cv2 as cv
# 读取图片
img = cv.imread('face.jpg')
# 转换为灰度图片
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 人脸检测器
face_cascade = cv.CascadeClassifier('Harrcascade_frontalface_default.xml')
# 识别人脸
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
print(x,y,w,h)
```
其中,图片坐标系以左上角为原点,`x,y`代表人脸区域左上角坐标,`w`代表宽度,`h`代表高度。
![](14.jpg)

@ -0,0 +1,73 @@
# 6.2.3 人脸性别识别
## 截取人脸ROI
在进行人脸性别识别时,不需要知道除了人脸之外的信息,所以需要根据上一节中检测到的人脸位置将人脸的`ROI`(感兴趣区域)截取下来。
假设检测到的人脸框为`face_rect`,那么可以根据人脸框得到人脸图像。
```python
x, y, w, h = face_rect
f_h, f_w = gray.shape[:2]
# 防止溢出
x = max(0, x)
y = max(0, y)
w = min(f_w - x, w)
h = min(f_h - y, h)
# 截取图像
face = frame[y: y + h, x: x + w, :]
# 保存图像
cv2.imwrite('face.jpg', face)
```
原图:
![](15.jpg)
提取到的人脸ROI
![](16.jpg)
## 提取HoG特征
方向梯度直方图(`Histogram of Oriented Gradient, HOG`)是一种在计算机视觉和图像处理中用来进行物体检测的特征描述方法。所谓特征描述方法,就是通过从图像中提取**有用信息**和丢弃无关信息来简化图像,并将信息运用于算法。
特征描述方法从图像中提取有用信息,那么在`HOG`中提取了图像那些有用信息呢?
其实,在图像中,物体的边缘和角落包含了关于物体形状的更多信息。也就是我们平时能看到的物体轮廓。如果能够提取出图像边缘和角落的信息,将非常有利于物体检测。
而对于图像,边缘和角落周围的**梯度**这个特征,变化幅度很大,所以在`HOG`特征描述方法中,使用梯度方向的分布(直方图)作为它的特征。
`OpenCV`中提供了提取`HOG`特征的接口。首先,使用`cv2.HOGDescriptor()`函数声明HOG特征描述方法代码如下
```python
hog = cv2.HOGDescriptor()
```
然后计算加载的图像的`HOG`特征值,代码如下:
```python
h = hog.compute(img)
```
完整的代码示例如下:
```python
import cv2
hog = cv2.HOGDescriptor()
img = cv2.imread(sample)
feature = hog.compute(img)
```
## 训练性别分类器
提取了人脸ROI的`HOG`特征后,就可以使用`sklearn`训练性别分类器了。
```python
from sklearn.svm import SVC
clf = SVC()
# hog_features为训练集中人脸ROI的HOG特征
clf.fit(hog_features, label)
pred = clf.predict(test_features)
```
Loading…
Cancel
Save