注:本文翻译自:Pedestrian Detection OpenCV。

你知道OpenCV里面已经内置的行人检测方法吗?在OpenCV里面,有一个预先训练好了的HOG+线性SVM模型,能够对图像和视频中的行人进行检测。如果你还不熟悉方向梯度直方图HOG和线性SVM方法,我建议你阅读方向梯度直方图和物体检测这篇文章,在这篇文章中,我对该框架分了6步进行讨论。

如果你已经熟悉了这个过程,或者你仅仅只是想看看OpenCV行人检测的代码,那么现在就打开一个新文件,并将它命名为detect.py,开始我们的编程之旅吧:

 1 # import the necessary packages
 2 from __future__ import print_function
 3 from imutils.object_detection import non_max_suppression
 4 from imutils import paths
 5 import numpy as np
 6 import argparse
 7 import imutils
 8 import cv2
 9
10 # construct the argument parse and parse the arguments
11 ap = argparse.ArgumentParser()
12 ap.add_argument("-i", "--images", required=True, help="path to images directory")
13 args = vars(ap.parse_args())
14
15 # initialize the HOG descriptor/person detector
16 hog = cv2.HOGDescriptor()
17 hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

第2-8行导入一些我们必要的包,我们导入print_function确保我们的代码同时在Python2.7和Python3上兼容,这样可以使得我们的代码能够在OpenCV2.4.X和OPenCV3上都能够工作,然后,从我的imutils包中我们导入non_max_suppression函数。

如果你还没有安装imutils,可以通过pip来安装:

$ pip install imutils

如果你已经安装了imutils,你需要把它更新到最新版(v0.3.1),在这个版本里面,包含了non_max_suppression函数的实现,以及其它一些微小的更新:

$ pip install --upgrade imutils

我已经在我的PyImageSearch博客上在两次讲到过非极大抑制(non-maxima suppression)方法,一次是在Python非极大抑制用于物体检测,一篇是在用Python实现更快的非极大抑制,无论是哪一种情形,非极大抑制的宗旨都是获取多个重叠的边框(bounding box),并且将他们减少至仅有一个边框。

图1:左图有很多检测错误的边框;右图采用非极大抑制后,使得我们可以抑制那些重叠的区域,将正确的边框留下来。

非极大抑制方法可以减少在进行行人检测过程中的假阳率。

第11-13行处理我们命令行传入的参数,这里,我们只需要一个切换--images,用它来传入待检测行人的图像目录。

最后,第16行和17行初始化我们的行人检测器。首先,我们调用hog = cv2.HOGDescriptor()来初始化方向梯度直方图描述子,然后,我们调用setSVMDetector来设置支持向量机(Support Vector Machine)使得它成为一个预先训练好了的行人检测器。

到了这里,我们的OpenCV行人检测器已经完全载入了,我们只需要把它应用到一些图像上:

 1 # import the necessary packages
 2 from __future__ import print_function
 3 from imutils.object_detection import non_max_suppression
 4 from imutils import paths
 5 import numpy as np
 6 import argparse
 7 import imutils
 8 import cv2
 9
10 # construct the argument parse and parse the arguments
11 ap = argparse.ArgumentParser()
12 ap.add_argument("-i", "--images", required=True, help="path to images directory")
13 args = vars(ap.parse_args())
14
15 # initialize the HOG descriptor/person detector
16 hog = cv2.HOGDescriptor()
17 hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
18
19 # loop over the image paths
20 for imagePath in paths.list_images(args["images"]):
21  # load the image and resize it to (1) reduce detection time
22  # and (2) improve detection accuracy
23  image = cv2.imread(imagePath)
24  image = imutils.resize(image, width=min(400, image.shape[1]))
25  orig = image.copy()
26
27  # detect people in the image
28  (rects, weights) = hog.detectMultiScale(image, winStride=(4, 4),
29      padding=(8, 8), scale=1.05)
30
31  # draw the original bounding boxes
32  for (x, y, w, h) in rects:
33      cv2.rectangle(orig, (x, y), (x + w, y + h), (0, 0, 255), 2)
34
35  # apply non-maxima suppression to the bounding boxes using a
36  # fairly large overlap threshold to try to maintain overlapping
37  # boxes that are still people
38  rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
39  pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)
40
41  # draw the final bounding boxes
42  for (xA, yA, xB, yB) in pick:
43      cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)
44
45  # show some information on the number of bounding boxes
46  filename = imagePath[imagePath.rfind("/") + 1:]
47  print("[INFO] {}: {} original boxes, {} after suppression".format(
48      filename, len(rects), len(pick)))
49
50  # show the output images
51  cv2.imshow("Before NMS", orig)
52  cv2.imshow("After NMS", image)
53  cv2.waitKey(0)

在第20行我们对我们的--images目录下的图像进行循环,这篇博文中使用的例子样本是从INRIA Person Dataset这个很流行的人物库上抽取的,更具体的说,是从GRAZ-01子集中抽取出来的,这些图片存放在源码目录下面了。

第23-25行载入磁盘中的图像,并且将图像裁剪到最大宽度为400个像素,之所以降低我们的图像维度(其实就是之所以对我们的图像尺寸进行裁剪)主要有两个原因:

  1. 减小图像的尺寸可以减少在图像金字塔中滑窗的数目,如此可以降低检测的时间,从而提高整体检测的吞吐量。
  2. 调整图像的尺寸能够整体提高行人检测的精度,也就是假阳率。

真正对图像中的行人进行检测的代码是在第28行和29行,通过调用detectMultiScalehog描述子方法。这个detectMultiScale方法构造了一个尺度scale=1.05的图像金字塔,以及一个分别在x方向和y方向步长为(4,4)像素大小的滑窗。

窗口的大小固定在32*128像素大小,这个设置是按照 seminal Dalal和Triggs论文来设置的。detectMultiScale函数会返回一个2-元组的rects,或者是图像中每一个行人的边框坐标(x,y),以及由SVM在每一次检测中返回的weights置信值(我们一般也成为分数,译者注)。

scale的尺度设置得越大,在图像金字塔中层的数目就越少,相应的检测速度就越快,但是尺度太大会导致行人出现漏检;同样的,如果scale设置得太小,将会急剧的增加图像金字塔的层数,这样不仅耗费计算资源,而且还会急剧地增加检测过程中出现的假阳数目(也就是不是行人的被检测成行人)。这表明,scale是在行人检测过程中它是一个重要的参数,需要对scale进行调参。我会在后面的文章中对detectMultiScale中的每个参数做些调研。

第32行和33行获取我们的初始边框,并将它们在图像上框出来。

不过,你将会看到在一些图像上有的行人框出来的框,有很多重叠的边框,如上面1图所示。

针对这种情况,我们有两种选择。一种选择是检测一个边框是否完全包含了另一个边框(你可以看看OpenV中的一些实现例子)。另外一种选择是应用非极大抑制方法,通过设置一个阈值来抑制那些重叠的边框,这就是第38行和39行所干的事。

注意:如果你想了解更多HOG框架和非极大抑制,我推荐你阅读方向梯度直方图和物体检测。在那篇博文中,你可以查看Python非极大抑制用于物体检测,以及后面更新的Malisiewicz方法。

在应用非极大抑制后,我们在第42行和43行画出最终的边框,在第46-48行中我们展示图像的一些基本信息,以及检测到的边框数目,在第51-53行,在屏幕最终显示我们输入的图像。

行人检测结果

为了看看我们写的行人检测脚本的实际效果,我们只需要执行下面命令:

$ python detect.py --images images

下图是一张行人检测的结果图:

图2:检测效果

上图我们检测到了站在警车旁的单个行人。

图3:在前景和背景中分别检测到了1个人

上面我们可以看到在前景中的男人被检测到了,同时背景中推着婴儿车的女人也检测到了。

图4:一个展示为什么用非极大抑制很重要的例子

图4的例子展示了为什么用非极大抑制很重要。detectMultiScale函数除了将正确的边框检测出来外,还把两个边框边框检测出来了,这两个错误的边框将图像中的行人覆盖了。通过使用非极大抑制,我们可以抑制错误的边框,只留下正确检测的边框。

图5:另一个展示非极大抑制效果的例子

我们再一次可以看到,有很多错误的边框被检测出来了,通过使用非极大抑制,我们可以抑制错误的边框,只留下正确检测的边框。

图6:在一个购物中心检测行人

图6在一个购物中心进行行人检测,图中,有两个人正向摄像头走进,另外一个人正远离摄像头,不管是哪种情形,我们的HOG检测方法都能够准确的检测出行人。在non_maxima_suppression函数中较大的overlapThresh能够确保那些部分重叠了的边框不会被抑制。

图7:在模糊图片中检测行人

老实说,我对上面图片的检测结果有点儿惊讶,因为一般而言HOG描述子在运动模糊的图片上检测效果不是很好,不过在这幅图像上,我们却将行人检测出来了。

图8:在室外街道上检测行人

这里有另外一个多个重叠边框的例子,不过因为我们的overlapThresh设置得比较大,所以这些边框没有被抑制,从而能够将正确的检测结果留下来。

图9:检测一张具有4个成员的家庭的图片

图9的例子展示了HOG+SVM行人检测器的多功能性,我们不仅能够检测到成年的男人,也能够检测到那三个小孩(注意:该检测器不能检测到躲藏在他老爸后面的小孩)。

图10:对路标标识进行行人检测

我将图10放在最后是因为我发觉这非常的有趣,我们可以很清楚的看到这只是一个路标标识,标识表示人行横道,然而,HOG+SVM检测器将它们在图中框出来了,实际上它们却并不是行人。

总结

在这篇博文中,我们已经学到了怎样使用OpenCV的库以及Python来进行行人检测。

实际上OpenCV库已经内置了一个预先训练好了的HOG+线性SVM检测器的模型,它是基于Dalal和Triggs论文里的方法来自动的实现图像中行人的检测。

虽然HOG的方法比Haar counter-part的精度要高,不过它仍需要对detectMultiScale进行合理的设置。在后面的博文中,我会对detectMultiScale中的每一个参数做一个调研,已经怎样调参的细节,并陈述在精度和性能之间的折中。

不管怎么说,我都希望你喜欢这篇博文!我正打算在后面给出更多的关于物体检测的教程,如果你希望这些教程出来后能够获得及时的通知,你可以考虑订阅我的博客。

我已经在PyImageSearch Gurus course里面包含了HOG+线性SVM的物体检测方法,你可以看看。

from: http://yongyuan.name/blog/pedestrian-detection-opencv.html

OpenCV行人检测相关推荐

  1. OpenCV计算机视觉编程攻略之行人检测

    OpenCV计算机视觉编程攻略之行人检测,OpenCV 提供了一个基于HOG 和SVM且经过训练的行人检测器,可以用这个SVM 分类器以不同尺度的窗口扫描图像,在完整的图像中检测特定物体. 原图如下: ...

  2. OpenCV实战【2】HOG+SVM实现行人检测

    目录 HOG是什么? HOG vs SIFT HOG步骤 HOG在检测行人中的方式 Opencv实现 HOGDescriptor的构造函数: 行人检测HOG+SVM步骤 简化版的HOG计算 HOG是什 ...

  3. opencv roberts算子_图像之HOG特征描述算子-行人检测

    4.1 简介 本次任务将学习一种在深度学习之前非常流行的图像特征提取技术--方向梯度直方图(Histogram of Oriented Gradients),简称HOG特征.HOG特征是在2005年C ...

  4. OpenCV实战4: HOG+SVM实现行人检测

    目前基于机器学习方法的行人检测的主流特征描述子之一是HOG(Histogram of Oriented Gradient, 方向梯度直方图)HOG 特征是用于目标检测的特征描述子,它通过计算和统计图像 ...

  5. opencv canny源码解析_行人检测 基于 OpenCV 的人体检测

    原文链接 行人检测 基于 OpenCV 的人体检测 - 热分享​hotdog29.com 在 2019年8月1日 上张贴 由 hotdog发表回复 行人检测 基于 OpenCV 的人体检测 我们都知道 ...

  6. opencv实现行人检测(C++)

    hog行人检测 本文主要介绍下opencv中怎样使用hog算法,因为在opencv中已经集成了hog这个类.其实使用起来是很简单的,从后面的代码就可以看出来.本文参考的资料为opencv自带的samp ...

  7. 【opencv】(11) 背景建模,帧差法、混合高斯模型,实战:行人检测,附python完整代码和数据集

    各位同学好,今天和大家分享一下opencv背景建模相关操作.主要介绍两种背景建模方法,帧差法和混合高斯模型. 案例简介:现有一份路口摄像机拍摄的行人流视频,通过背景建模方法,区分背景和前景,完成行人识 ...

  8. opencv 使用SVM+HOG训练行人检测分类器(INRIA Person Dataset训练集)

    目录 1.训练过程(即代码流程) 2.模型及结果优缺点分析 3.模型建立中发现的问题及改进方法 4.行人检测OpenCv 代码(C++) 1.训练过程(即代码流程) 1. 准备训练样本集合: 包括正样 ...

  9. pythonopencv检测行人_行人检测 基于 OpenCV 的人体检测

    原文链接行人检测 基于 OpenCV 的人体检测 - 热分享​hotdog29.com 行人检测 基于 OpenCV 的人体检测 我们都知道,无论性别,种族或种族如何,我们的身体都具有相同的基本结构. ...

最新文章

  1. select 和 order by
  2. xshell使用命令总结
  3. 【NOIP模拟】T1 发电机(递推逆元+期望)
  4. 油价新年首涨:“五连跌”终结 一箱油多花4元
  5. BZOJ 2039: [2009国家集训队]employ人员雇佣
  6. Ubuntu12.04安装JDK6
  7. 关于使用asp.net调试器出现的问题及相关解决方法
  8. rfc3095中文版_RFC3095
  9. hihoCoder #1468 : 2-SAT·hihoCoder新春晚会(2-SAT 输出字典序最小的方案)
  10. ROJECT SERVER如何与OUTLOOK集成使用
  11. linux-noshell的模式
  12. SGU 186.The Chain
  13. 洛谷——P1657 选书
  14. 计算机错误 引用无效名称,有关无效的引用的疑难解答
  15. Python实现连点器
  16. CFAR检测MATLAB仿真
  17. Mac 修改 hosts 命令,以及使其立马生效
  18. MCE | 打破 Western Blot 玄学操作
  19. 无向图的邻接矩阵平方的实际意义解释
  20. 富爸爸系列:富爸爸穷爸爸实践

热门文章

  1. 十分钟学习自然语言处理概述
  2. ICML论文|这违反直觉的“升噪”方法,反而能很好的解决激活函数梯度弥散的问题
  3. JVM - 再聊GC垃圾收集算法及垃圾收集器
  4. Oracle-awrddrpt.sql比较两个AWR差异报告
  5. Spring OXM-XStream流化对象
  6. 学习笔记Flink(二)—— Flink数据流模型、时间窗口和核心概念
  7. java程序运行堆栈分析
  8. 得力助手 消防员的 消防机器人_消防机器人:消防员的“得力助手”(科技大观)...
  9. 使用onenote记HTML笔记,如何在Windows 10中使用OneNote做笔记
  10. python中有没有switch_Python为什么没有switch/case语句?