2020 简单车道线检测实现(上)

分享一个简单车道识别示例,介绍如何使用 opencv 识别图像中车道线,有助于对车辆进行导航,虽然比较基础,主要目的让大家熟悉 opencv 一些特征提取的方法。我们随后介绍如何应用深度学习来做车道线检测的任务。

读取路况图像

这里我们主要使用 opencv 来做这件事,所以首先引入 opencv 库。

import cv2

使用 imread 方法来读取图片,使用 imshow 将图片显示出来,简单地观测一下图片。路况还是比较好,几乎没有什么车辆、而且没有弯道,大家可能会说是不是过于简单,实际上没有那么简单,做事可以先从简单开始,一步一步来,把简单做好了才能做好复杂的事。

image = cv2.imread('test_image.jpg')
cv2.imshow('result',image)
cv2.waitKey(0)
test_image

去色

在 opencv 中提供一些用于检测(识别)边缘、角点等这些特征点方法通常需要我们输入一张灰度图,这也就是为什么我们需要先对图片进行去色处理。在计算机视觉中提取关键点是大部分任务中不可缺少。关键点可以带来更多关于图片的信息,帮助机器理解图像的语义。而且关键点通常就是在图像灰度有变化的地方。

image = cv2.imread('test_image.jpg')
# copy not reference to
lane_image = np.copy(image)

gray = cv2.cvtColor(lane_image,cv2.COLOR_RGB2GRAY)
cv2.imshow('result',gray)
cv2.waitKey(0)

降低噪点

第二项工作还需要对图片进行模糊(blur),通过模糊来减少图片的噪点这样更有利于查找边界。

在灰度图每一个像素都是一个单一值来表示,表示图像灰度值,通过改变深色周围的像素灰度值来实现模糊(或者说是平滑)这里我们会创建一个卷积核。高斯模糊本质上是低通滤波器,输出图像的每个像素点是原图像上对应像素点与周围像素点的加权和,原理并不复杂。如何了解了卷积神经网络这应该就不难懂了。

从图中我们可以看出高斯模糊对图片边缘进行模糊处理。

图片是由表示灰度的像素值组成的,像素值差距大地方会明显梯度下降感觉会造成图片不够平滑,或者说不连续,这个很好理解,这就需要我们模糊对这些比较锐利的边缘进行处理。看这张图 90 值周围都是 255 所以 90 点在 255 就是感觉不太协调。我们可以通过 90 周围像素值来影响 90 这个值,通过求这些值平均值方式来减少 90 和其周围像素值之间差异。

卷积核

这个就是由加权值组成的卷积核,卷积核在图像进行游走,通过将像素值通过计算其周围值的均值或者带有权重的值来计算其值。

高斯模糊之所以叫高斯模糊,是因为运用了高斯卷积核来进行图片模糊成的密度函数
f(x) = \frac{1}{\sqrt{2 \pi} \sigma} e^{-\frac{(x -\mu)^2}{2 \sigma^2}}

blur = cv2.GaussianBlur(gray,(5,5),0)
模糊处理图

Canny边缘检测算法

获取图片的边缘信息是底层数字图像处理的基本任务之一。边缘信息对进一步提取高层语义信息有很大的影响。这也有助于我们对图像物体进行识别


过渡分为两种一个强过渡一种是弱过渡


过渡强弱是我们判断是否边缘的依据,我们可以通过阈值来指定那些是我们要找的过渡将这些过渡作为边缘,那些是我们忽略过渡。


激活

这里就需要一个类似神经网激活函数,来确定那些是用于判断边缘那些不是。


canny = cv2.Canny(blur,50,150)
cv2.imshow('result',canny)
canny

整理代码

import cv2
import numpy as np

def canny(image):
    gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
    blur = cv2.GaussianBlur(gray,(5,5),0)
    canny = cv2.Canny(blur,50,150)
    return canny
# read image
image = cv2.imread('test_image.jpg')
# copy not reference to
lane_image = np.copy(image)
canny = canny(lane_image)

cv2.imshow('result',canny)
cv2.waitKey(0)

将对图片进行去色、模糊以及边缘检测一系列处理都整理到 canny 这个函数。然后通过调用该函数进行

import matplotlib.pyplot as plt
plt.imshow(canny)
plt.show()

应用遮罩

通常这样 camera 都是安装在车前盖上来对车道线进行识别。

def region_of_interest(image):
    height = image.shape[0]
    ploygons = np.array([[(200,height),(1100,height),(550,250)]])
    mask = np.zeros_like(image)
    cv2.fillPoly(mask,ploygons,255)
    return mask
cv2.imshow('result',region_of_interest(canny))
cv2.waitKey(0)
mask

通过 bitwise_and 对两个图像的每一个像素做 and (与) 运算,来将遮罩应用图像,这个如果大家有 Photoshop 经验应该不难理解这个操作,也就是仅保留我们感兴趣区域。

def region_of_interest(image):
    height = image.shape[0]
    ploygons = np.array([[(200,height),(1100,height),(550,250)]])
    mask = np.zeros_like(image)
    cv2.fillPoly(mask,ploygons,255)
    masked_image = cv2.bitwise_and(image,mask)
    return masked_image

霍夫变换(Hough Transform)

从图中看这就是一个再简单不过函数, y = mx + b 表示线性方程的直线。

直线方程

在下图中我们可以看到 y=mx+b 方程形状是由斜率 m 和截距 b 决定的,所以根据 m 和 b 的取值就线性方程,建立一个坐标系通过点表示出来就是霍夫空间。m 和 b 就是在初中时候就学到的方程的斜率和截距。

那么也就是在霍夫空间中每一个点对应坐标中一条直线。

m 是表示方程的斜率,然后以点(在霍夫空间中的坐标为 m 和 b) 来对应左侧的直线。

通过一个例子来说明,在下图(左侧)中 y = 3 + 2 可以在(右侧)霍夫空间中点(3,2)对应该方程 。

知道通过一点的直线是任意多,y = 2x + 8 通过坐标系中的一点,该方程在霍夫空间对应点为(2,8),大家都已经了解了他们之间对应关系了吧。

方程 y = 5x+2 也会通过这一点,然后在将这个方程对应到霍夫空间,依次类推大家可以自己动手尝试一下举出一些列通过一点方程,然后将他们对应表示在霍夫空间。

大家不难看出通过某一点的方程,看似没有什么规律不过在霍夫方程中我们似乎看出这些经过某一点所有方程在霍夫空间中对应的点都会出现在一条直线上。

同样我们可以再举一点,然后将通过这一点的直线描绘在霍夫空间表示出来,在让这些方程对应点在霍夫空间连接成线,我们发现这两直线有了一个交点。

其实在霍夫空间两条直线交点所对应方程就是通过这两个点的直线的表示的方程



依次类推


这样我们回到我们处理的道路图,说了这么多有关霍夫变换,就是为了通过多个点来找他们共享(也就是穿过这些点)的那条直线。


实际情况应该没有上面那么理想,我们无法找到一条直线精准地通过所有点,只能模糊地在一定范围内找到一条符合直线。所以我们可以将霍夫空间划分为一些小格子来扩大范围。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355