当前位置:网站首页>车的换道检测
车的换道检测
2020-11-06 01:28:00 【人工智能遇见磐创】
作者|Hitesh Valecha 编译|VK 来源|Towards Data Science

在本教程中,我们将学习如何使用计算机视觉和图像处理来检测汽车是否在路上变道。
你一定听说过使用Opencv haar cascade可以检测人脸、眼睛或汽车、公共汽车等物体?这次让我们用这个简单的检测方法来构建一些很酷的东西。
1.数据集
在本教程中,道路上汽车的视频文件被用作数据集。此外,我们可以使用图像数据集检测图像中的车辆,但在这里,当车辆变道时,我们会用弹出窗口发出警报,因此对于这些动态信息,视频输入更为可行。
2.输入
我们使用OpenCV的haar cascade来检测汽车的坐标,输入是道路上汽车的视频文件
cascade_src = 'cascade/cars.xml'
video_src = 'dataset/cars.mp4'
cap = cv2.VideoCapture(video_src)
car_cascade = cv2.CascadeClassifier(cascade_src)
cv2.VideoCapture()方法用于捕获输入的视频,一个视频通常是每秒25帧图像(fps)。在捕获到输入后,循环提取帧,并利用haar cascade检测,在循环中围绕汽车绘制一个矩形,以获得一致性,同时对捕获的帧执行其他操作。
while(1):
# 获取每一帧
_, frame = cap.read()
cars = car_cascade.detectMultiScale(frame, 1.1, 1)
for (x,y,w,h) in cars:
roi = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2) #感兴趣区域
在OpenCV中使用BGR而不是RGB,因此(0,0,255)将在汽车上绘制一个红色矩形,而不是蓝色。

3.图像处理
我们使用帧,但是如果帧的分辨率非常高,它将减慢执行的操作,此外,帧包含噪声,可以使用模糊来减少,这里使用高斯模糊。
现在,让我们看看一些图像处理的概念
3.1 HSV框架
在这篇文章中,我们使用从cv2.VideoCapture()捕获的帧中获取HSV帧,仅突出显示车辆转弯的点,并遮住剩余的道路和在道路上直线行驶的车辆。设置上限和下限以定义HSV中的颜色范围,以查看汽车变道的点,并用作帧的掩码。下面是用于获取此信息的代码片段-
# 使用模糊消除视频帧中的噪声
frame = cv2.GaussianBlur(frame,(21,21),0)
# 转换BGR到HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 在HSV中定义颜色范围,以查看车辆改变角度的点
lower_limit = np.array([0,150,150])
upper_limit = np.array([10,255,255])
# HSV图像限制阈值
mask = cv2.inRange(hsv, lower_limit, upper_limit)
3.2腐蚀和膨胀
腐蚀和膨胀是用于图像处理的两种基本形态学操作。腐蚀算子对核函数的区域有局部最小值的影响,核函数是模板或掩码。腐蚀是用来减少图像中的斑点噪声。膨胀是图像与核的卷积,它具有局部最大算子的作用。当像素被添加到图像中平滑物体的边界时,应用膨胀来恢复一些丢失的区域。
从HSV帧的第一步生成的掩码现在用基本的形态学操作(腐蚀和扩张)来处理。生成的帧是通过将帧和掩码之间的按位与运算得到ROI(感兴趣区域)。
kernel = np.ones((3,3),np.uint8)
kernel_lg = np.ones((15,15),np.uint8)
# 被称为腐蚀的图像处理技术用于降噪
mask = cv2.erode(mask,kernel,iterations = 1)
# 称为膨胀的图像处理技术,用来恢复失去的部分区域
mask = cv2.dilate(mask,kernel_lg,iterations = 1)
# 除了感兴趣的区域,其他地方都变成黑色
result = cv2.bitwise_and(frame,frame, mask= mask)
3.3车道检测
利用canny边缘检测算子结合Hough线变换进行车道检测。

#车道检测
def canny(frame):
gray=cv2.cvtColor(frame,cv2.COLOR_RGB2GRAY)
blur=cv2.GaussianBlur(gray,(5,5),0)
canny=cv2.Canny(blur,50,150)
return canny
def region_of_interest(frame):
height=frame.shape[0]
polygons=np.array([
[(0,height),(500,0),(800,0),(1300,550),(1100,height)]
])
mask=np.zeros_like(frame)
cv2.fillPoly(mask,polygons,255)
masked_image=cv2.bitwise_and(frame,mask)
return masked_image
def display_lines(frame,lines):
line_image=np.zeros_like(frame)
if lines is not None:
for line in lines:
x1,y1,x2,y2=line.reshape(4)
cv2.line(line_image, (x1, y1), (x2, y2), (0, 255, 0), 3)
return line_image
lane_image=np.copy(frame)
canny=canny(lane_image)
cropped_image=region_of_interest(canny)
lines=cv2.HoughLinesP(cropped_image,2,np.pi/180,100,np.array([]),minLineLength=5,maxLineGap=300)
line_image=display_lines(lane_image,lines)
frame=cv2.addWeighted(lane_image,0.8,line_image,1,1)
cv2.imshow('video', frame)
4.等高线
canny边缘检测器等算法用于查找边缘像素图像中的边缘分界,但它并没有告诉我们如何找到对象或实体不能结合的点和边,这里我们可以使用OpenCV实现的cv2.findContours()作为轮廓的概念。
定义-“轮廓表示图像中曲线的点的列表。”
轮廓由序列表示,每个序列都对下一个点的位置信息进行编码。我们在roi中多次运行cv2.findConteurs()来获取实体,然后使用cv2.drawContours()绘制轮廓区域。轮廓可以是点、边、多边形等,所以在绘制等高线时,我们做多边形近似,求出边的长度和区域的面积。
函数cv2.drawContours()的工作原理是从根节点开始绘制一棵树(数据结构),然后连接后续点、边界框和Freeman链码。
thresh = mask
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# 定义轮廓的最小面积(忽略min以下的所有值)
min_area = 1000
cont_filtered = []
# 过滤掉最小面积以下的所有轮廓线
for cont in contours:
if cv2.contourArea(cont) > min_area:
cont_filtered.append(cont)
cnt = cont_filtered[0]
# 围绕轮廓画出矩形
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(frame,[box],0,(0,0,255),2)
rows,cols = thresh.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv2.line(frame,(cols-1,righty),(0,lefty),(0,255,0),2)
找到轮廓后的另一个重要任务是匹配它们。匹配轮廓意味着我们有两个独立的计算轮廓来相互比较,或者有一个轮廓与一个抽象模板进行比较。
5.特征矩
我们可以通过计算轮廓矩来比较两个轮廓。“特征矩是轮廓的总特征,通过将轮廓的所有像素相加来计算。”

力矩类型
空间特征矩:m00, m10, m01, m20, m11, m02, m30, m21, m12, m03.
中心特征矩:mu20, mu11, mu02, mu30, mu21, mu12, mu03.
Hu特征矩:有七个Hu特征矩(h0-h6)或(h1-h7),这两个符号都使用。
我们使用cv2.fitEllipse()计算特征矩并在点上拟合椭圆。从轮廓线和特征矩中找到角度,因为改变车道需要45度旋转,这被视为汽车转弯角度的阈值。

M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)
print('x= ', cx, ' y= ', cy, ' angle = ', round(rect[2],2))
if(round(rect[2],2))<-45:
# print('Lane change detected')
popupmsg('Lane change detected')
现在,我们可以使用Tkinter来创建一个简单的弹出窗口来警告变化,而不仅仅是打印变化的检测结果。
if(round(rect[2],2))<-45:
popupmsg('Lane change detected')
def popupmsg(msg):
popup = tk.Tk()
popup.wm_title("Message")
label = ttk.Label(popup, text=msg, font=NORM_FONT)
label.pack(side="top", fill="x", pady=10)
B1 = ttk.Button(popup, text="Okay", command = popup.destroy)
B1.pack()
popup.mainloop()

在车架上画矩形,用绿线测量角度


6.总结和未来
在本教程中,将使用车道变化检测方法探索智能汽车导航的一个小演示。
计算机视觉正在迅速发展,它的应用不仅在汽车的局部导航,而且在火星上的导航和产品检测领域也在进步,甚至在医学应用中也在开发和用于早期在X射线图像中检测癌症和肿瘤。
单击此处获取GitHub帐户的源代码:https://github.com/Hitesh-Valecha/Car_Opencv
参考文献
- Bradski, Gary and Kaehler, Adrian, Learning OpenCV: Computer Vision in C++ with the OpenCV Library, O’Reilly Media, Inc., 2nd edition, 2013, @10.5555/2523356, ISBN — 1449314651.
- Laganiere, Robert, OpenCV Computer Vision Application Programming Cookbook, Packt Publishing, 2nd edition, 2014, @10.5555/2692691, ISBN — 1782161481.
原文链接:https://towardsdatascience.com/lane-change-detection-computer-vision-at-next-stage-914973f96f4b
欢迎关注磐创AI博客站: http://panchuang.net/
sklearn机器学习中文官方文档: http://sklearn123.com/
欢迎关注磐创博客资源汇总站: http://docs.panchuang.net/
版权声明
本文为[人工智能遇见磐创]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4253699/blog/4697463
边栏推荐
- 9.2.1 xmlconfigbuilder constructor (xmlconfigbuilder analysis) - SSM in depth analysis and project practice
- nlp模型-bert从入门到精通(二)
- ThreadLocal原理大解析
- 聆听无声的话语:手把手教你用ModelArts实现手语识别
- Big data real-time calculation of baichenghui Hangzhou station
- Asp.Net Core学习笔记:入门篇
- htmlcss
- 对pandas 数据进行数据打乱并选取训练机与测试机集
- es5 类和es6中class的区别
- Python 基于jwt实现认证机制流程解析
猜你喜欢

drf JWT认证模块与自定制

Probabilistic linear regression with uncertain weights

Big data real-time calculation of baichenghui Hangzhou station

Python machine learning algorithm: linear regression

滴滴 Elasticsearch 集群跨版本升级与平台重构之路

按指定基准对齐的分组运算

阻塞队列之LinkedBlockingQueue分析

Using class weight to improve class imbalance

APReLU:跨界应用,用于机器故障检测的自适应ReLU | IEEE TIE 2020

如何在Windows Server 2012及更高版本中将域控制器降级
随机推荐
Big data real-time calculation of baichenghui Hangzhou station
面经手册 · 第12篇《面试官,ThreadLocal 你要这么问,我就挂了!》
6.9.1 flashmapmanager initialization (flashmapmanager redirection Management) - SSM in depth analysis and project practice
不能再被问住了!ReentrantLock 源码、画图一起看一看!
TF flags的简介
2020十大最佳大数据分析工具,果断收藏
Jumpserver高可用集群部署:(六)SSH代理模块koko部署并实现系统服务管理
【QT】 QThread部分原始碼淺析
Python 基于jwt实现认证机制流程解析
經典動態規劃:完全揹包問題
6.8 multipartresolver file upload parser (in-depth analysis of SSM and project practice)
一文带你了解 Jest 单元测试
8.1.1 handling global exceptions through handlerexceptionresolver
技术总监,送给刚毕业的程序员们一句话——做好小事,才能成就大事
JVM内存区域与垃圾回收
tensorflow之tf.tile\tf.slice等函数的基本用法解读
深入了解JS数组的常用方法
How to select the evaluation index of classification model
keras model.compile损失函数与优化器
通用的底层埋点都是怎么做的?