在 OpenCV 中训练 Haar 级联目标检测器

在OpenCV中使用Haar级联分类器很简单。您只需提供XML文件中的训练模型即可创建分类器。然而,从头开始训练一个分类器并非那么简单。在本教程中,您将看到训练过程应该是什么样的。特别是,您将学习:

  • 在OpenCV中训练Haar级联的工具是什么
  • 如何准备训练数据
  • 如何运行训练

通过我的书《OpenCV 机器学习启动您的项目。它提供了带有可用代码自学教程


让我们开始吧。

在 OpenCV 中训练 Haar 级联目标检测器
图片由 Adrià Crehuet Cano 拍摄。保留部分权利。

概述

本文分为五个部分,它们是:

  • OpenCV中训练级联分类器的问题
  • 环境设置
  • 级联分类器训练概述
  • 准备训练数据
  • 训练Haar级联分类器

OpenCV中训练级联分类器的问题

OpenCV已经存在多年,并且有许多版本。在撰写本文时,OpenCV 5正在开发中,推荐版本是OpenCV 4,准确地说是版本4.8.0。

OpenCV 3和OpenCV 4之间进行了大量的清理工作。最值得注意的是,大量代码被重写。这种变化是巨大的,许多函数都发生了变化。这包括训练Haar级联分类器的工具。

级联分类器不是像SVM那样可以轻松训练的简单模型。它是一个使用AdaBoost的集成模型。因此,训练涉及多个步骤。OpenCV 3有一个命令行工具来帮助进行此类训练,但该工具在OpenCV 4中已损坏。修复程序尚未提供。

因此,只能使用OpenCV 3训练Haar级联分类器。幸运的是,在训练完成后,您可以将其丢弃,并在将模型保存到XML文件后恢复到OpenCV 4。这正是您将在本文中完成的操作。

OpenCV 3和OpenCV 4不能在Python中同时存在。因此,建议为训练创建一个单独的环境。在Python中,您可以使用`venv`模块创建一个虚拟环境,它只是创建一组单独的已安装模块。替代方案是使用Anaconda或Pyenv,它们是相同理念下的不同架构。在上述所有选项中,您应该认为Anaconda环境最容易完成此任务。

想开始学习 OpenCV 机器学习吗?

立即参加我的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

环境设置

如果您使用Anaconda,会更容易一些,您可以使用以下命令创建并使用一个名为“cvtrain”的新环境:

如果您发现 `opencv_traincascade` 命令可用,则说明您已准备就绪。

如果您使用的是`pyenv`或`venv`,则需要更多步骤。首先,创建环境并安装OpenCV(您应该注意到与Anaconda生态系统不同的包名)

这允许您使用OpenCV运行Python程序,但您没有用于训练的命令行工具。要获取这些工具,您需要按照以下步骤从源代码编译它们:

  1. 下载OpenCV源代码并切换到3.4分支

     
  2. 创建与存储库目录分离的构建目录
  3. 使用 `cmake` 工具准备构建目录,并指向 OpenCV 存储库

     
  4. 运行 `make` 进行编译(您可能需要先在系统中安装开发人员库)

     
  5. 您需要的工具将在 `bin/` 目录中,如上述最后一个命令所示

所需的命令行工具是`opencv_traincascade`和`opencv_createsamples`。本文的其余部分假设您已具备这些工具。

级联分类器训练概述

您将使用OpenCV工具训练一个**级联分类器**。该分类器是一个使用AdaBoost的集成模型。简单来说,会创建多个较小的模型,每个模型在分类方面都很弱。结合起来,它就成为一个具有良好精确度和召回率的强大分类器。

每个**弱分类器**都是一个二元分类器。为了训练它们,您需要一些正样本和负样本。负样本很容易:您向OpenCV提供一些随机图片,并让OpenCV选择一个矩形区域(如果这些图片中没有目标对象,则更好)。然而,正样本是以图像和对象完美地位于其中的边界框的形式提供的。

一旦提供了这些数据集,OpenCV将从中提取Haar特征,并使用它们来训练许多分类器。Haar特征是通过将正样本或负样本划分为矩形区域而获得的。划分方式涉及一些随机性。因此,OpenCV需要时间来找到最佳方法来为这项分类任务推导Haar特征。

在OpenCV中,您只需以OpenCV可读取的图像文件格式(例如JPEG或PNG)提供训练数据。对于负样本,只需一个包含文件名的纯文本文件。对于正样本,需要一个“信息文件”,这是一个纯文本文件,其中包含文件名、图片中对象的数量以及相应的边界框的详细信息。

用于训练的正样本数据应采用二进制格式。OpenCV提供了一个工具`opencv_createsamples`,用于从“信息文件”生成二进制格式。然后,这些正样本与负样本一起提供给另一个工具`opencv_traincascade`,以运行训练并以XML文件格式生成模型输出。这就是您可以加载到OpenCV Haar级联分类器中的XML文件。

准备训练数据

让我们考虑创建一个**猫脸**检测器。为了训练这样的检测器,您首先需要数据集。一种可能性是Oxford-IIIT宠物数据集,位于此位置:

这是一个800MB的数据集,按照计算机视觉数据集的标准来说是一个小型数据集。图像以Pascal VOC格式进行标注。简而言之,每张图像都有一个相应的XML文件,如下所示:

XML文件告诉您它引用的是哪个图像文件(上面示例中的`Abyssinian_100.jpg`),以及它包含什么对象,边界框位于`<bndbox></bndbox>`标签之间。

要从XML文件提取边界框,您可以使用以下函数:

上述函数返回的字典示例如下:

有了这些,就可以轻松创建用于训练的数据集:在Oxford-IIT宠物数据集中,照片要么是猫,要么是狗。您可以将所有狗的照片作为负样本。然后,所有猫的照片将作为正样本,并设置适当的边界框。

OpenCV期望的正样本“信息文件”是一个纯文本文件,每行格式如下:

文件名后面的数字是该图像上边界框的数量。每个边界框都是一个正样本。后面跟着的是边界框。每个框由其左上角的像素坐标以及框的宽度和高度指定。为了获得Haar级联分类器的最佳结果,边界框应与模型期望的纵横比相同。

假设您下载的宠物数据集位于`dataset/`目录中,您应该看到文件组织如下:

有了这个,使用以下程序创建正样本的“信息文件”和负样本文件列表就很容易了:

该程序扫描数据集中所有 XML 文件,然后提取每个文件中的边界框(如果是猫的照片)。列表 negative 将保存狗照片的路径。列表 positive 将保存猫照片的路径以及上述格式的边界框,每行作为一个字符串。循环结束后,这两个列表将作为文件 negative.datpositive.dat 写入磁盘。

negative.dat 的内容很简单。positive.dat 的内容如下:

在运行训练之前,需要将 positive.dat 转换为二进制格式。这可以通过以下命令行完成:

此命令应在与 positive.dat 相同的目录中运行,以便能找到数据集图像。此命令的输出将是 positive.vec,也称为“vec 文件”。在执行此操作时,需要使用 -w-h 参数指定窗口的宽度和高度。这是为了在写入 vec 文件之前,将边界框裁剪的图像调整为这个像素大小。这还应与运行训练时指定的窗口大小匹配。

训练Haar级联分类器

训练分类器需要时间。它分多个阶段完成。每个阶段都会写入中间文件,一旦所有阶段完成,您将获得保存为 XML 文件的训练模型。OpenCV 期望所有这些生成的文件都存储在一个目录中。

运行训练过程确实很简单。我们考虑创建一个新目录 cat_detect 来存储生成的文件。创建目录后,您可以使用命令行工具 opencv_traincascade 运行训练

请注意,positive.vec 用作正样本,negative.dat 用作负样本。另请注意,-w-h 参数与您之前在 opencv_createsamples 命令中使用的相同。其他命令行参数解释如下:

  • -data :存储训练好的分类器的位置。此目录应已存在
  • -vec :正样本的 vec 文件
  • -bg :负样本列表,也称为“背景”图像
  • -numPos :每个阶段训练中使用的正样本数量
  • -numNeg :每个阶段训练中使用的负样本数量
  • -numStages :要训练的级联阶段数量
  • -w -h :对象的像素大小。这必须与使用 opencv_createsamples 工具创建训练样本时使用的相同
  • -minHitRate :每个阶段的最小所需真阳性率。在满足此条件之前,阶段训练不会终止。
  • -maxFalseAlarmRate :每个阶段的最大所需假阳性率。在满足此条件之前,阶段训练不会终止。
  • -maxDepth :弱树的最大深度
  • -maxWeakCount :每个阶段弱树的最大数量

并非所有这些参数都是必需的。但您应该尝试不同的组合,看看是否能训练出更好的检测器。

在训练过程中,您将看到以下屏幕:

您应该注意到,$N$ 个阶段的训练运行编号为 0 到 $N-1$。某些阶段可能需要更长的训练时间。开始时,会显示训练参数以明确正在进行的操作。然后,在每个阶段,都会逐行打印一个表格。该表格显示三列:特征编号 N、命中率 HR(真阳性率)和误报率 FA(假阳性率)。

在第 0 阶段之前,您应该看到打印的 minHitRate 为 0.995,maxFalseAlarmRate 为 0.5。因此,每个阶段将找到许多 Haar 特征,直到分类器能够将命中率保持在 0.995 以上,同时误报率低于 0.5。理想情况下,您希望命中率为 1,误报率为 0。由于 Haar 级联是一种集成,如果您在多数情况下是正确的,则会得到正确的预测。近似地,您可以考虑一个 $n$ 阶段的分类器,其命中率为 $p$,误报率为 $q$,则总命中率为 $p^n$,总误报率为 $q^n$。在上述设置中,$n=10$,$p>0.995$,$q<0.5$。因此,总误报率将低于 0.1%,总命中率将高于 95%。

此训练命令在现代计算机上需要超过 3 小时才能完成。输出文件将命名为 cascade.xml,位于输出目录下。您可以使用以下示例代码检查结果:

结果将取决于您的模型训练得如何,也取决于您传递给 detectMultiScale() 的参数。有关如何设置这些参数,请参阅之前的文章。

上述代码在一个数据集图像中运行检测器。您可能会看到如下结果:

使用训练好的 Haar 级联对象检测器的示例输出

您会看到一些误报,但猫的脸已经被检测到。有多种方法可以提高质量。例如,您上面使用的数据集没有使用方形边界框,而您在训练和检测时使用了方形形状。调整数据集可能会有所改善。同样,您在训练命令行上使用的其他参数也会影响结果。但是,您应该知道 Haar 级联检测器速度非常快,但使用的阶段越多,它就会越慢。

进一步阅读

如果您想深入了解此主题,本节提供了更多资源。

书籍

网站

总结

在这篇文章中,您学习了如何在 OpenCV 中训练 Haar 级联对象检测器。特别是,您学习了

  • 如何为 Haar 级联训练准备数据
  • 如何在命令行中运行训练过程
  • 如何使用 OpenCV 3.x 训练检测器并在 OpenCV 4.x 中使用训练好的模型

开始使用 OpenCV 进行机器学习!

Machine Learning in OpenCV

学习如何在图像处理项目中使用机器学习技术

...以高级方式使用 OpenCV,超越像素处理

在我的新电子书中探索如何实现
OpenCV 机器学习

它提供带有所有可用 Python 代码自学教程,让您从新手成长为专家。它为您提供了
逻辑回归随机森林支持向量机k 均值聚类神经网络等等……所有这些都使用 OpenCV 中的机器学习模块

通过动手练习开启你的深度学习之旅


查看内容

在 OpenCV 中训练 Haar 级联对象检测器 的 2 条回复

  1. Pedro 2024 年 10 月 29 日下午 12:11 #

    当我运行 opencv_traincascade 时,出现“command not found”(命令未找到)错误

    • James Carmichael 2024 年 10 月 30 日上午 9:14 #

      嗨 Pedro... opencv_traincascade 命令用于在 OpenCV 中训练级联分类器(通常用于人脸或对象检测),但如果您遇到“command not found”错误,很可能意味着该命令不在您的系统 PATH 中,或者 OpenCV 未正确安装。

      以下是故障排除步骤:

      1. **检查 OpenCV 安装**
      – 确保 OpenCV 已安装了包含 opencv_traincascade 的额外模块。
      – 如果 OpenCV 是从源代码编译的,请验证安装路径是否包含可执行文件。

      2. **定位可执行文件**
      – 您可以使用 findlocate 来查找 opencv_traincascade
      bash
      find / -name "opencv_traincascade" 2>/dev/null

      – 如果找到可执行文件,请记下其位置。

      3. **添加到 PATH**
      – 如果可执行文件位于标准目录之外(例如 /usr/local/bin),您可以将其添加到您的 PATH 中
      bash
      export PATH=$PATH:/path/to/opencv/bin

      – 将 /path/to/opencv/bin 替换为 opencv_traincascade 所在的目录。将此行添加到您的 .bashrc.zshrc 文件中,以使其永久生效。

      4. **使用 Contrib 模块重新构建 OpenCV**
      – 如果您没有找到该命令,可能是因为 OpenCV 未使用 contrib 模块构建。您可以按如下方式安装包含这些模块的 OpenCV
      bash
      git clone https://github.com/opencv/opencv.git
      git clone https://github.com/opencv/opencv_contrib.git
      mkdir -p build && cd build
      cmake -D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules ../opencv
      make -j4
      sudo make install

      – 这将确保包含 opencv_traincascade

      完成这些步骤后,请再次尝试运行 opencv_traincascade。如果问题仍然存在,请告诉我,我可以帮助您进一步排除故障。

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。