专栏首页决策智能与机器学习算法集锦(11)| 自动驾驶 | 基于HOG和SVM的车辆识别算法

算法集锦(11)| 自动驾驶 | 基于HOG和SVM的车辆识别算法

本文旨在介绍一种基于方向梯度直方图(HOG)和支持向量机(SVM,Support Vector Machines)的车辆检测和跟踪算法。该算法在OpenCV和Sklearn环境下开发,经不断优化后在实际路况下得到了成功的应用。

为实现该算法,需要完成以下几步:

  • 在标注的训练集中提取HOG特征
  • 在图像数据集(图片中有车辆或无车辆)中训练分类器
  • 在每一帧视频图像下进行窗口滑移(sliding window),以获得图像的子区域
  • 在各个子区域(subregion)中应用训练好的分类器
  • 创建热点图(heat map),并逐帧的进行车辆检测和跟踪

方向梯度直方图

注意到,不同车辆的颜色千变万化,而它们的形状则基本一致,因此用车辆的形状参数来代表车辆具有更高的鲁棒性。通常,通过分析不同方向的梯度值可以获得 物体的形状特征,为了弱化车辆在形状上的细微差异,采用方向梯度直方图(Histogram of Oriented Gradient,HOG)进行形状检测具有更好的效果。

HOG是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子,通过计算和统计图像局部区域的梯度方向直方图来构成特征。首先,把样本图像分割为若干个像素的单元,把梯度方向平均划分为多个区间,在每个单元里面对所有像素的梯度方向在各个方向区间进行直方图统计,得到一个多维的特征向量。每相邻的单元构成一个区间,把一个区间内的特征向量联起来得到多维的特征向量,用区间对样本图像进行扫描,扫描步长为一个单元。最后,将所有块的特征串联起来,就得到了车辆的特征。

特征提取

我们需要设置number_of_rientations, pixels_per_cellcells_per_block等参数来计算图像各个通道的HOG值。其中number_of_rientations 参数决定每个单元的像素梯度在直方图中用几个线段表示;pixels_per_cell 代表每个单元(cell)中包含的像素的行数和列数;cells_per_block 指定直方图进行归一化的局部区域。通过设置这些参数,可以提取出更可靠的特征集。此外,还可以应用transfor_sqrt 来消除阴影和光照变化的影响。

下面,我们来看看不同参数下提取的车辆特征情况。

feature_params = {
  'color_model': 'yuv',                # hls, hsv, yuv, ycrcb
  'bounding_box_size': 64,             # 64 pixels x 64 pixel image
  'number_of_orientations': 11,        # 6 - 12
  'pixels_per_cell': 8,                # 8, 16
  'cells_per_block': 2,                # 1, 2
  'do_transform_sqrt': True
}
# [3 x 3 block positions] x [2 x 2 cells per block] x [11 orientations] x [3 channels] = 1,188 features
source = FeatureSourcer(feature_params, vehicle_image)
vehicle_features = source.features(vehicle_image)
rgb_img, y_img, u_img, v_img = source.visualize()
feature_params = {
  'color_model': 'hls',                # hls, hsv, yuv, ycrcb
  'bounding_box_size': 64,             # 64 pixels x 64 pixel image
  'number_of_orientations': 12,        # 6 - 12
  'pixels_per_cell': 16,                # 8, 16
  'cells_per_block': 2,                # 1, 2
  'do_transform_sqrt': True
}
# [7 x 7 block positions] x [2 x 2 cells per block] x [12 orientations] x [3 channels] = 7,056 features
YUV Feature Extraction Time Taken: 471.28
HLS Feature Extraction Time Taken: 1781.44

分类器训练

我们采用支持向量机(SVM)作为分类器策略。图像数据集共包括8792个含车辆的图片和8968个不含车辆的图片。为了减小训练误差,在将原始特征输入分类器前,我们用scaler 函数对其进行转换处理。

# Feature Extraction...
for img in vehicle_imgs:
  vehicles_features.append(source.features(img))
for img in nonvehicle_imgs:
  nonvehicles_features.append(source.features(img))
# Scaling Features...
unscaled_x = np.vstack((vehicles_features, nonvehicles_features)).astype(np.float64)
scaler = StandardScaler().fit(unscaled_x)
x = scaler.transform(unscaled_x)
y = np.hstack((np.ones(total_vehicles), np.zeros(total_nonvehicles)))
# Training Features...
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, random_state = rand.randint(1, 100))
svc = LinearSVC()
svc.fit(x_train, y_train)
accuracy = svc.score(x_test, y_test)
HLS Features Classifier Accuracy: 0.9878
YUV Features Classifier Accuracy: 0.9834
class BinaryClassifier:
  def __init__(self, svc, scaler):
    self.svc, self.scaler = svc, scaler
  def predict(self, f):
    f = self.scaler.transform([f])
    r = self.svc.predict(f)
    return np.int(r[0])

滑动窗口

我们通过滑动窗口来获得视频图像的不同子区域(subregion),然后在其上应用分类器来判断该区域是否包含车辆。考虑到计算HOG特征非常耗时,因此我们仅在开始时计算整个图片的HOG特征值,然后再在需要时才计算子区域的HOG特征,这样可以有效的提高计算效率。

通常我们仅对地平线以下的区域进行搜索,因此车辆不可能“开”到天上去。

cls = BinaryClassifier(svc, scaler)
src = FeatureSourcer(feature_params, temp_frame)
slider = Slider(sourcer = src, classifier = cls, increment = 8)
window_sizes = 80, 120, 150, 180
strip_positions = 410, 390, 380, 380
boxed_images, strips = [], []
for ws, wp in zip(window_sizes, strip_positions):
  bounding_boxes = slider.locate(frame = this_frame, window_size = ws, window_position = wp)
  boxed_image = put_boxes(this_frame, bounding_boxes)
  boxed_images.append(boxed_image)
  strips.append(slider.strip())
show_images(strips)
show_images(boxed_images)

热点图

在连续的视频中,可能会出现交叉识别(overlapping detection)或者假阳性识别(false positive detection)问题。我们可以采用热点图(hot map)方法来解决该问题。

首先,先设置一个空白的“白板”,当分类器检测到车辆时,就在增加相应区域的“热度值”,并随着视频的变化循环往复的进行检测。最终,有车辆存在的区域就会变得越来越“热”,从而识别出车辆的准确位置。应用时,通常会设置一个阙值来剔除假阳性出现的区域,有车辆存在的区域一直会保持“热态”,而偶尔出现的假阳性检测结果随着时间的变化迅速变为“冷态”。

this_heatmap = HeatMap(frame = temp_frame, thresh = 20, memory = 30) 
this_heatmap.reset()
for sz, pos in zip(ws, wp):
  bounding_boxes = slider.locate(frame = this_frame, window_size = sz, window_position = pos)
  this_heatmap.update(bounding_boxes)
heatmap, thresholded_map, labeled_map = this_heatmap.get()
labeled_frame = this_heatmap.draw(this_frame)

总 结

本文介绍的算法的流程为:首先通过HOG提取图像的特征,然后将其输入到SVM分类器中进行车辆识别。通过滑动窗口技术来检测图像的不同区域,获得车辆的准确位置。此外为了解决交叉识别和假阳性检测问题,应用了热点图技术。

实际应用发现,HLS和YUV色彩编码模式下的图像更适用于HOG特征提取,并且YUV模式的运算效率较HLS高,因此建议采用YUV色彩编码进行车辆检测。

本文分享自微信公众号 - 决策智能与机器学习(AIfreak),作者:Ethon

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 智能技术赋能道路智能化,促进光伏产业新发展 | 智能交通 | 解读行业

    随着智能技术的快速发展,智慧城市在建设过程中覆盖范围更广、涉及领域更多。特别是光伏发电将会借着智能技术之东风迎来新的发展,其应用领域更加广泛。

    用户7623498
  • CB Insights AI 100 之机器人篇

    近日, CB Insights 发布了第二届全球最强AI 创业公司榜单 AI 100。

    用户7623498
  • 算法集锦(17)|自然语言处理| 比特币市场情绪分析算法

    本次算法分享,我们提供了一种可以通过Twitter(或微博)信息进行加密货币市场预测的方法。该方法利用Twitter上的数据来预测人们对加密货币市场的情绪:贪婪...

    用户7623498
  • 硬盘基本知识(磁头、磁道、扇区、柱面)

    java404
  • 工控系统网络安全,一场没有硝烟的战争

    2018年8月,世界500强的半导体制造公司台积电生产园区电脑遭大规模病毒入侵,导致新竹、台中、台南三大生产基地全线停工,损失高达17.4亿元。而造成如此轰动的...

    SDNLAB
  • 详解安恒“PMPE”工控安全防护技术体系

    随着两化融合、工业4.0、工业物联网的快速发展,工业化与信息化的融合趋势越来越明显,工业控制系统也在利用最新的网络技术来提高系统间的集成、互联以及信息化管理水平...

    安恒信息
  • ConcurrentLinkedQueue和LinkedBlockingQueue用法

    作者: Ruthless 关注 - 28 粉丝 - 2969 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出)。J...

    Spark学习技巧
  • canvas-颜色选择器 原

    (3)颜色信息的函数主要包括,获取鼠标所在点的位置,通过getImageData获取鼠标所在点的像素对象,并最终获得rgba信息

    tianyawhl
  • python算法与数据结构-队列(44)

      队列的定义:队列是一种特殊的线性表,只允许在表的头部(front处)进行删除操作,在表的尾部(rear处)进行插入操作的线性数据结构,这种结构就叫做队列。进...

    Se7eN_HOU
  • 在RHEL / CentOS 8中创建网桥的3种方法

    网桥是将两个或多个网段互连并在它们之间提供通信的数据链路层设备。它创建单个网络接口,以从多个网络或网段中建立单个聚合网络。它根据主机的MAC地址(存储在MAC地...

    用户6543014

扫码关注云+社区

领取腾讯云代金券