基于 OpenCV 的车辆变道检测,计算机视觉+图像处理技术

本期教程我们将和小伙伴们一起研究如何使用计算机视觉和图像处理技术来检测汽车在行驶中时汽车是否在改变车道!大家一定听说过使用 OpenCV 的 haar 级联文件可以检测到面部、眼睛等,但是如果目标是汽车,公共汽车呢?

01. 数据集

我们将道路上汽车的视频文件用作数据集。当然可以使用图像数据集检测来汽车,但是由于汽车在变道时我们需要通过弹出窗口提供警报,因此对于这些动态情况,视频输入更为可行。

02. 输入

第一步是提供要在本教程中使用的输入 - OpenCV 的 haar 级联文件,用于检测汽车的坐标,道路上的汽车的视频文件 -

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 级联文件检测到的坐标,我们在循环中在汽车周围绘制一个矩形,以在对捕获的帧执行其他操作时获得一致性。

while(1):# Take each frame    _, 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)   #ROI is region of interest

在 OpenCV 中,使用 BGR 而不是 RGB,因此(0,0,255)将在汽车上绘制一个红色矩形,而不是蓝色。

03. 图像处理

如果帧的分辨率很高,则会减慢执行的操作,此外,该帧还包含噪声,可以使用模糊降低噪声,这里使用高斯模糊。

3.1 HSV 框架

在此,我们使用从 cv2.VideoCapture()捕获的帧中获得的 HSV 帧仅突出显示汽车转弯的点,并遮挡其余道路和在道路上直行的汽车。设置上限和下限阈值是为了定义 HSV 中的颜色范围,以查看汽车改变车道的点,并用作框架的遮罩。以下是用于获取此代码的代码段 -

#canceling noise in the video frames using blurframe = cv2.GaussianBlur(frame,(21,21),0)    # Convert BGR to HSVhsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)    # define range of color in HSV to see the points at which the car is changing angleslower_limit = np.array([0,150,150])upper_limit = np.array([10,255,255])    # Threshold the HSV image to get only the thresholded colorsmask = 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)    # image processing technique called the erosion is used for noise reduction    mask = cv2.erode(mask,kernel,iterations = 1)    # image processing technique called the dilation is used to regain some lost area    mask = cv2.dilate(mask,kernel_lg,iterations = 1)    # Bitwise-AND to get black everywhere else except the region of interest    result = cv2.bitwise_and(frame,frame, mask= mask)

3.3 车道检测

canny 边缘检测器与霍夫线变换一起用于检测车道。

canny 边缘检测(作者提供的图像)

04. 边缘检测

诸如 canny 边缘检测器之类的算法用于查找将图像中的边缘像素,但是由于我们无法融合某些点和边缘,因此它无法找到实际对象,在这里我们可以使用 OpenCV 中的 cv2.findContours()实现轮廓的查找。

定义 -“轮廓是代表图像中曲线的点的列表。” 等高线由序列表示(序列是结构的链表),每个序列都编码有关下一点位置的信息。我们在 ROI 中多次运行 cv2.findContours()以获得实体,然后使用 cv2.drawContours()绘制轮廓区域。等高线可以是点,边,多边形等,因此在绘制等高线时,我们进行多边形近似,以找到边的长度和区域的面积。函数 cv2.drawContours()的工作方式是从根节点开始绘制一棵树(数据结构),然后将后续点,边界框和 freeman 链代码连接在一起。

找到轮廓后的另一个重要任务是匹配它们。轮廓匹配意味着我们有两个单独的计算轮廓相互比较,或者轮廓与抽象模板相比较。

thresh = maskcontours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)# define a minimum area for a contour (ignoring all values below min)min_area = 1000cont_filtered = []# filter out all contours below a min_areafor cont in contours:  if cv2.contourArea(cont) > min_area:    cont_filtered.append(cont)
cnt = cont_filtered[0]# draw the rectangles around contoursrect = 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)

05. 中心矩

我们可以通过计算轮廓矩来比较两个轮廓。“中心矩是通过将轮廓的所有像素相加而得出的轮廓的总体特征。”

中心矩型 -

  • 空间矩: 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 度旋转,这被认为是汽车转弯角度的阈值。

现在,我们不仅可以打印检测变化的车道,还可以使用 Tkinter 作为一个简单的弹出窗口来提醒更改。

使用 Greenline 测量角度,并在框架中的汽车上绘制矩形

弹出警报(作者提供的图片)

输出

06. 总结

在本教程中,使用车道变更检测方法探索了智能汽车导航的小型演示。计算机视觉正在迅速发展,其应用不仅在汽车的本地导航中而且在火星导航和产品检查领域中也在不断发展,甚至医疗应用也正在开发中,并可以在早期用于检测 X 射线图像中的癌症和肿瘤阶段。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/241398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端工程注入版本号

文章目录 一、前言二、webpack三、vite四、最后 一、前言 容器化时代,当页面出现问题时,如果你的新版本有可能已经修复了,那样你再排查它就没有意义了。为什么不一定是最新版本呢?一是可能是缓存作祟,二是可能运维成员…

<JavaEE> 基于 TCP 的 Socket 通信模型

目录 一、认识相关API 1)ServerSocket 2)Socket 二、TCP字节流套接字通信模型概述 三、回显客户端-服务器 1)服务器代码 2)客户端代码 一、认识相关API 1)ServerSocket ServerSocket 常用构造方法ServerSocke…

互联网+建筑工地源码,基于微服务+Java+Spring Cloud +Vue+UniApp开发

一、智慧工地概念 智慧工地就是互联网建筑工地,是将互联网的理念和技术引入建筑工地,然后以物联网、移动互联网技术为基础,充分应用BIM、大数据、人工智能、移动通讯、云计算、物联网等信息技术,通过人机交互、感知、决策、执行和…

使用Python自己写了一个Renpy 汉化插件

之前看了很多教程都是Renpy怎么解包、怎么创建翻译文件,对翻译过程没有过多讲解,就根据翻译文件写了一个小程序,如果需要的可以自行下载使用。 使用方法: 1.按照正常unrpa的解包方式renpy进行解包; 2.使用renpy-sdk…

React 的 Suspense 和 ErrorBoundary 这关系也能有?

Suspense 组件想必大家都用过&#xff0c;一般是和 React.lazy 结合用&#xff0c;用来加载一些异步组件。 比如这样一个组件&#xff1a; // src/Aaa.jsx export default function Aaa() {return <div>aaa</div> }就可以在另一个组件里用 lazy Suspense 异步加…

C++之数据类型转换(全)

截止C20标准模板库同时提供了高级数值转换函数和低级数值转换函数&#xff0c;下面就仔细讲解一下这些数值转换函数的用法 一、数值转换 1、高级数值转换函数 std 名称空间包含很多辅助函数&#xff0c;以便完成数值和字符串之间的转换&#xff0c;它们定义在<string>中…

测试开发体系介绍——测试体系介绍-L3

目录&#xff1a; 测试框架体系TDDDDTBDDATDD介绍 测试框架是什么&#xff1f;测试框架的价值&#xff1a;测试框架的收益&#xff1a;常见测试框架类型&#xff1a;TDDBDDBehaviorDrivenDevelopmentATDDAcceptanceTestDrivenDevelopmentMBTModelBasedTestingDDTDataDrivenTes…

案例147:基于微信小程序的酒店管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

Golang 泛型实现原理

文章目录 1.有 interface{} 为什么还要有泛型&#xff1f;2.泛型实现原理2.1 类型参数泛型函数泛型数据结构 2.2 类型约束2.3 编译时生成虚拟方法表单态化 Go 的实现 3.小结参考wenxian 泛型&#xff08;Generics&#xff09;是 Go 语言在较早版本缺失的一个特性&#xff0c;直…

MFC 视图窗口

目录 视图窗口概述 视图窗口的使用 视图窗口创建流程 命令消息 WM_COMMAND 处理顺序 对象关系 视图窗口概述 作用&#xff1a;提供了一个用于显示数据的窗口 关于视图窗口 视图类是用来展示用户&#xff0c;文档类是用来存储和管理数据视图窗口是覆盖掉框架窗口的客户区…

vue的插槽解析

插槽 好处&#xff1a;组件的内容结构可定制 用slot插槽进行占位 语法: 子组件中通过slot进行占位 理解&#xff1a;父组件&#xff0c;在子组件标签嵌套的内容就会被渲染到slot地方 一、默认插槽 //子组件 <slot>slot插槽</slot> //方法一<slot name"…

qt,滚动条,放大缩小拖动图片

头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QLabel> #include <QWheelEvent> #include <QMouseEvent> #include <QtDebug>#include <math.h> #include <QPainter> #include <QTimer>…

详解Vue3中的插槽(slot)

本文主要介绍Vue3中的插槽&#xff08;slot&#xff09;。 目录 一、在普通写法中使用插槽&#xff08;slot&#xff09;作用域插槽默认插槽 二、在setup写法中使用插槽&#xff1a;注意事项 在Vue3中&#xff0c;插槽&#xff08;slot&#xff09;是一种用于在父组件中向子组件…

Unity矩阵平移旋转缩放Matrix4x4

Unity矩阵平移旋转缩放Matrix4x4 Unity中的矩阵&#xff08;Matrix4x4&#xff09;创建自定义模型平移矩阵缩放矩阵旋转矩阵 Unity中的矩阵&#xff08;Matrix4x4&#xff09; 最近在研究帧同步定点数物理系统中需要自定义定点数矩阵&#xff0c;所以在这里分享下基础的矩阵案…

蓝牙物联网在智能家居中的应用前景

物联网智能家居系统是应用物联网技术&#xff0c;在传统家居环境下将各种零散无序的电器整合成统一整体&#xff0c;实现家电的全程自动控制&#xff0c;满足用户高效管理需求的一种新型家居模式。 其主要的子系统有家居感知系统、家庭网络系统、智能家居控制管理系统等&#x…

使用教程之【SkyWant.[2304]】路由器操作系统,破解移动【Netkeeper】校园网【小白篇】

许多高校目前饱受Netkeeper认证的痛苦&#xff0c;普通路由器无法使用&#xff0c; 教你利用SkyWant的Netkeeper认证软件来使你的SkyWant路由器顺利认证上网&#xff0c;全宿舍又可以合作共赢了&#xff01; 步骤一&#xff1a;正确连接网线&#xff0c;插电开机 正确连接网…

SQLITE如何同时查询出第一条和最后一条两条记录

一个时间记录表&#xff0c;需要同时得到整个表或一段时间内第一条和最后一条两条记录&#xff0c;按如下方法会提示错误&#xff1a;ORDER BY clause should come after UNION not before select * from sdayXX order by op_date asc limit 1 union select * from sday…

分布式Session使用步骤

目录 1. 为什么用分布式Session2. Spring-Session使用步骤2-1. 添加依赖2-2. yml配置 1. 为什么用分布式Session 将一个项目部署到多台服务器上时&#xff0c;多台服务器的Tomcat的Session不共享。那么就有可能造成Session数据不一致情况&#xff0c;所以此时就需要使用分布式…

Gateway API

Gateway API 目录 原文链接 https://onedayxyy.cn/docs/GatewayAPI 本节实战 实战名称&#x1f6a9; 实战&#xff1a;Gateway API在istio里的安装及测试-2023.12.23(测试失败) 前言 Gateway API 是由 SIG-NETWORK 社区管理的开源项目&#xff0c;项目地址&#xff1a;http…

Java设计模式-单例模式(Singleton)

Java中实现单例模式有几种不同的方式,每种方式都有其特点和适用场景。下面是两种常用的实现方式:懒汉式和饿汉式。 懒汉式(线程安全) 懒汉式单例是指在第一次被引用时才会创建实例。为了确保线程安全,可以使用同步方法或同步块。 public class SingletonLazy {private sta…