注意
转到结尾 下载完整示例代码。或通过 Binder 在浏览器中运行此示例
使用级联分类器进行人脸检测#
此计算机视觉示例演示了如何使用基于机器学习的物体检测框架来检测图像中的人脸。
首先,您将需要一个 xml 文件,从中可以读取训练数据。该框架可以使用通过多块局部二值模式特征 (参见 MB-LBP) 训练的训练文件,以及具有注意力级联的 Gentle Adaboost。因此,检测框架也可以使用 OpenCV 中的 xml 文件。您可以在其中找到训练用于检测猫脸、侧面脸和其他事物的文件。但是,如果您要检测正面脸,则相应文件已包含在 scikit-image 中。
接下来,您必须为 detect_multi_scale
函数指定参数。您可以在此处找到每个参数的含义。
第一个是 scale_ratio
。为了找到所有的人脸,该算法在多个尺度上执行搜索。这是通过更改搜索窗口的大小来完成的。最小的窗口大小是训练中使用的窗口大小。此大小在训练参数的 xml 文件中指定。 scale_ratio
参数指定在每一步中搜索窗口增加的比率。如果您增加此参数,搜索时间会减少,精度也会降低。因此,某些尺度上的人脸可能无法检测到。
step_ratio
指定用于在图像的每个尺度上搜索人脸的滑动窗口的步长。如果此参数等于 1,则搜索所有可能的定位。如果该参数大于 1,例如,2,则窗口将移动 2 个像素,并且不会搜索所有可能的定位以查找人脸。通过增加此参数,我们可以减少算法的工作时间,但精度也会降低。
min_size
是尺度搜索过程中搜索窗口的最小尺寸。 max_size
指定窗口的最大尺寸。如果您知道要搜索的图像中人脸的大小,则应尽可能精确地指定这些参数,因为您可以避免进行昂贵的计算,并可能减少误检的数量。通过增加 min_size
参数,您可以节省大量时间,因为大部分时间都花在了最小的尺度上的搜索上。
min_neighbor_number
和 intersection_score_threshold
参数用于聚类同一张人脸的过多检测结果,并过滤掉误检。真实的人脸通常在其周围有许多检测结果,而误检通常只有单个检测结果。第一个算法搜索集群:如果两个矩形检测结果之间的交叉得分大于 intersection_score_threshold
,则将它们放在同一个集群中。交叉得分使用方程 (交叉区域) / (小矩形比率) 计算。所述交叉准则选择高于交并比,以避免小矩形在大型矩形内部具有较小交叉得分时的极端情况。然后,每个集群使用 min_neighbor_number
参数进行阈值处理,这将保留包含相同或更多检测结果的集群。
您还应该考虑到误检是不可避免的,如果您想要一个非常精确的检测器,则必须使用 OpenCV 训练级联实用程序 自己进行训练。
from skimage import data
from skimage.feature import Cascade
import matplotlib.pyplot as plt
from matplotlib import patches
# Load the trained file from the module root.
trained_file = data.lbp_frontal_face_cascade_filename()
# Initialize the detector cascade.
detector = Cascade(trained_file)
img = data.astronaut()
detected = detector.detect_multi_scale(
img=img, scale_factor=1.2, step_ratio=1, min_size=(60, 60), max_size=(123, 123)
)
fig, ax = plt.subplots()
ax.imshow(img, cmap='gray')
for patch in detected:
ax.axes.add_patch(
patches.Rectangle(
(patch['c'], patch['r']),
patch['width'],
patch['height'],
fill=False,
color='r',
linewidth=2,
)
)
plt.show()
脚本的总运行时间:(0 分钟 0.338 秒)