机器学习实战:车辆检测

当我们开车时会经常关注环境,尤其关注那些潜在障碍物的位置,不管是汽车、行人还是道路上的物体​​。 同样,当我们开发自动驾驶车辆所需的智能和传感器时,最重要的一点是这些车辆能够检测到障碍物,因为它加强了车辆对环境的理解。 其中一种最重要的障碍物是道路上的其他车辆,因为它们很可能是我们车道或邻近道路上最大的物体,因此构成潜在的危险。

在众多的文献中,研究人员已经开发了许多用于障碍物检测的技术,从传统的计算机视觉技术到深度学习都有。 在本文中,我们使用一种传统的计算机视觉技术 — 方向梯度直方图(HOG)并结合被称为支持向量机(SVM)的机器学习算法来构建车辆检测器。

如果想马上学习Python和机器学习方面的知识,推荐你使用汇智网的Python机器学习

数据集

我们使用的数据集概述如下:

  • 车辆图像:〜9K
  • 非车辆图像:〜9K
  • 图像尺寸:64x64

该数据集来自GTI车辆影像数据库和KITTI Vision Benchmark Suite。 下面展示了数据集中的一些样本:

sample

我们可以清楚地看到,数据集中包含了车辆和非车辆的图像。 非车辆图像往往是道路的其他元素,如沥青、道路标志或路面。 车辆和非车辆的区别非常明显。 大多数图像中车辆都位于图的中心,但可能有不同的朝向,这有助于机器学习模型的泛化,很好。 此外,数据集中的汽车类型、颜色和照明条件都是多种多样的。

分类特征的研究

方向梯度直方图(HOG)

自从Navneet DalalBill Triggs在其论文《基于HOG的行人检测》中展示出令人印象深刻的结果后,将HOG用于物体检测就流行开来。 Satya Mallick这篇文章中很好的解释了HOG的原理和算法,对于那些希望深入理解HOG的人来说值得一看。

我们首先针对HOG算法的以下参数,在RGB图像上尝试不同的配置:

  • 方向数(用o表示)
  • 每个单元的像素数(用px / c表示)

每个图像块的单元数最初固定为2(用c / bk表示) 。 下面的图片显示了在RGB格式的车辆图像样本上获得的结果:

hog

仅仅是基于肉眼的观察,如下的配置看起来似乎可以为车辆生成独特的梯度特征:

  • 方向数:11
  • 单元像素数:14
  • 图像块单元数:2

现在让我们尝试下不同的图像块单元数量:

cells

对于人眼来说,不同的单元数量配置所生成的特征,彼此间并没有显著的差异。 理想情况下,我们希望压缩特征空间以便更快地计算。 因此将一个图像块的单元数设定为3

颜色空间

现在我们需要找出最合适的颜色空间,因为看起来3RGB通道的HOG特征太相似了,看起来特征的变化范围还不够大。

我们尝试在多个颜色空间中生成以下输出:

color space

对于某些颜色通道来说,很难解释所生成的HOG特征。 有趣的是,YUVYCrCbLAB这几个颜色空间中的第一个颜色通道似乎就足以捕捉我们正在寻找的梯度特征。 在另外两个颜色空间HSVHLS中,HOGValueLightness通道捕捉到了车辆最重要的特征。

为了证实这个假设,让我们尝试在一个车辆的不同颜色空间的影像上计算HOG

channel

在上面这样的光线黯淡的图像,我们可以观察到,携带最多亮度信息的通道HOG的结果并不好。 因此,我们必须考虑所有的色彩通道以便捕捉尽可能多的特征。 最后,我们得到的参数配置如下:

  • 使用YCrCb色彩空间的所有通道
  • HOG方向数:11
  • 每个单元的HOG像素数:14
  • 每个图像块的HOG单元数:2

我们还将添加了颜色信息来强化特征集。 要做到这一点,我们只需要使用32bin来生成所有颜色通道的直方图,如下所示:

def color_histogram(img, nbins=32, bins_range=(0, 256)):
    """
    Returns the histograms of the color image across all channels, as a concatenanted feature vector
    """
    # Compute the histogram of the color channels separately
    channel1_hist = np.histogram(img[:,:,0], bins=nbins, range=bins_range)
    channel2_hist = np.histogram(img[:,:,1], bins=nbins, range=bins_range)
    channel3_hist = np.histogram(img[:,:,2], bins=nbins, range=bins_range)

    # Concatenate the histograms into a single feature vector and return it
    return np.concatenate((channel1_hist[0], channel2_hist[0], channel3_hist[0]))

分类器

分类器负责将指定的图像分类为车辆/非车辆。 为此目的,我们按以下步骤进行实现:

  • 从数据集加载图像
  • 从图像中提取特征
  • 特征归一化
  • 将数据拆分为训练集和测试集
  • 使用适当的参数构建分类器
  • 使用训练数据对分类器进行训练

正如上一节所讨论的,我们决定只保留一个特征:YCrCb图像Y通道上计算的HOG特征向量。

我们随机地分割数据集,留下20%用于测试。 然后使用sklearn.preprocessing.StandardScaler 来归一化样本数据。

由于没有足够的时间来测试众多的分类器,我们主观选择了支持向量机 (SVM),因为在物体检测的相关文献中,SVMHOG是常见的组合。 而且,我们使用了rbf核函数的SVC ,因为它精度最高,虽然要比LinearSVC慢一些, 但是在一系列图像上的测试表明,使用rbf核的SVC,其物体检测能力要强得多。

我们使用GridSearchCV函数获得了以下参数的理想值:核类型( linearrbf ), C ( 1,100,1000,1000 )和gamma ( auto,0.01,0.1,1 )之间 。 最佳的配置可以实现99%以上的准确度,参数如下:

  • kernel = rbf
  • C = 100
  • gamma = auto

滑动窗口检测

我们创建多个尺寸的滑动窗口,大小从64x64到256x256像素,然后使用分类器来识别这些窗口,并且只保留正向的预测。 我们在屏幕底部使用较大的滑动窗户,因为这一区域的车辆通常较大,而在屏幕上方则使用较小的滑动窗口。 在y方向小于350像素的区域(即图像上部)不进行车辆检测。 下图显示了单元的重叠设置为4时的滑动窗口检测示例:

slide window

热图和阈值化

我们的分类器有时(不可避免地)会将非车辆区域错误地识别为车辆。 为了避免在视频上突出显示这些误报区域,我们可以利用滑动窗口中的冗余信息,计算某一区域被检测为车辆的次数。首先使用scipy.ndimage.measurements的label函数来标记具有重叠窗口的对象。 然后通过物体最小边界框来提取每个标签的位置。我们只保留识别为车辆的次数超过特定阈值的区域。 根据实验,我们发现阈值4就可以取得不错的结果。 下面的照片展示了热图和阈值的工作原理:

heatmap

第一个小热图表示分类器的原始检测结果,而第二个小热图表示阈值区域,红色强度随着重叠窗口数量的增加而增加。 右侧的最后一张小图显示了分类器预测为车辆的所有窗口。 在这个例子中,我们实际上使用的是LinearSVC ,它比rbf核的SVC更容易得到错误的预测。

帧聚合

为了进一步强化我们的处理流水线,我们决定每隔n帧平滑所有的检测窗口。 为此,我们缓存在( n-1)* f + 1n* f之间所有检测到的窗口,其中n是正标量,表示当前所在的帧分组。下面的类封装了检测到的物体:

class DetectedObject:
    """
    The DetectedObject class encapsulates information about an object identified by our detector
    """
    def __init__(self, bounding_box, img_patch, frame_nb):
        self.bounding_box = bounding_box
        self.img_patch = img_patch 
        self.frame_nb = frame_nb
        self.centroid = (int((bounding_box[0][0] + bounding_box[1][0]) / 2), int((bounding_box[0][1] + bounding_box[1][1]) / 2))
        self.similar_objects = []
...

每当组中的当前帧或下一帧中检测到一个新目标时,检查过去是否检测到类似的对象,如果是的话,我们追加那个类似的对象,从而增加这个对象在多个帧中的计数。 在帧n * f处,我们只保留那些检测超过m次的物体(及其边界框),从而在流水线中实现某种双重滤波。

在下面的gif中可以看到,当我们有一个覆盖两辆汽车的单个边界框和每个汽车都有自己的边界框之间有一秒钟的时间:帧聚合逻辑必须等待,直到两个窗口出现足够多的时间显示他们:

gif

进一步改进

这是一个棘手的项目,特别是对于那些选择更传统的计算机视觉和机器学习方法而不是深度学习的人。 以下步骤非常耗时:

  • 确定最合适的特征(HOG,图像颜色直方图等)
  • 探索HOG参数+色彩空间的最佳组合
  • 使用网格搜索来找到最合适的分类器

下一步,可以采用更快的像R-CNNYOLO架构的深度学习方法,因为这些方法现在是用于目标检测问题的最先进的解决方案,并且可以实时运行。 尽管如此,为了更好地理解传统的机器学习技术并帮助建立特征选择的直觉,这是一个有价值的练习。 而且,我震惊于像HOG这样简单而有美感的技术,依然可以输出可靠的结果。

如果你喜欢这篇文章,记得关注我的头条号:新缸中之脑!

原文:Teaching Cars To See — Vehicle Detection Using Machine Learning And Computer Vision

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值