基于YOLOv5+Hough变换的目标检测和车道线检测

2023-10-30

这学期做的一个大作业,实现了对行驶过程中车辆、行人以及车道线的检测。

1.B站视频演示
2.Github仓库链接


一、实现效果

第一个是其他车道线检测里拿的视频素材,第二个是b站中国街景的驾车实拍视频。

主要的检测流程是:

  1. 选择一段你喜欢的路况视频,按帧分解为图片(提供视频帧分解程序mp4tofigure.py
  2. 图片预处理,设定Canny高低阈值以及ROI标定(提供动态调整Canny高低阈值的辅助程序 Canny_check.py,交互式ROI标定的辅助程序roi_setup.py
  3. 送入主程序main.py,进行目标检测和车道线检测。
  4. 检测结果为图片,可以转换成视频(提供导出视频程序figure2video.py

在这里插入图片描述
在这里插入图片描述

二、环境配置

一个可以运行YOLOv5的python环境,与之前的一篇博客Realsense D435i Yolov5目标检测实时获得目标三维位置信息差不多。
仓库结构

三、基于YOLOv5的目标检测

这部分没啥特别的,就是套YOLOv5框架。不过由于原版的YOLOv5代码过于冗长,为后期与车道线检测的代码相结合,对YOLOv5源代码进行适当的简化封装,将检测过程基于一个封装的函数实现,如下所示。Canvas为返回的图像矩阵,class_id_list为检测到类的id列表,xyxy_list为检测框的角点位置像素坐标,conf_list为置信度列表。

canvas, class_id_list, xyxy_list, conf_list = model.detect(color_image)

选用YOLOv5s权重,其中前八类为为交通相关。
['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light']
效果如下
在这里插入图片描述

四、基于Hough变换的车道线检测

基于Hough变换的车道线检测流程为:输入图片——Canny轮廓检测——设定ROI——Hough变换提取直线——结果信息绘制。

4.1 前置工作 Canny阈值设定

首先需要调整一下Canny的阈值,使得轮廓检测出来的车道线连续平滑。
这里提供一个可以动态调整Canny高低阈值的辅助程序 Canny_check.py
在这里插入图片描述

import cv2
para=[300,400]
def nothing(*arg):
    pass
cv2.namedWindow('Trackbar')
cv2.resizeWindow('Trackbar', 400, 100)
cv2.createTrackbar('low', 'Trackbar', para[0], 1000, nothing)
cv2.createTrackbar('high', 'Trackbar', para[1], 1000, nothing)

source=cv2.imread("test.jpg")
img=source.copy()
cv2.namedWindow("canny", 0)
while(1):
    img = source.copy()
    low = cv2.getTrackbarPos('low', 'Trackbar')
    high = cv2.getTrackbarPos('high', 'Trackbar')
    img = cv2.Canny(img, low, high)
    cv2.imshow("canny", img)
    cv2.waitKey(20)

4.2 前置工作 ROI标定

接着需要标定出车道线检测范围的ROI
这里提供一个交互式ROI标定的辅助程序roi_setup.py,按顺时针顺序左键进行像素标定,右键完成像素点连接,中键清除所有标记,最终可以导出标定结果。
在这里插入图片描述
在这里插入图片描述

import cv2
import numpy as np

def mouse(event, x, y, flags, param):
    img1 = img.copy()
    if event == cv2.EVENT_LBUTTONDOWN:

        x_list.append(x)
        y_list.append(y)
        # print(x_list)
        for i in range(len(x_list)):
            xy = "(%d,%d)" % (x_list[i], y_list[i])
            cv2.circle(img1, (x_list[i], y_list[i]), 1, (0, 0, 255), thickness=2)
            cv2.putText(img1, xy, (x_list[i], y_list[i]), cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), thickness=2)
        cv2.imshow("image", img1)  # 显示坐标
    if event == cv2.EVENT_RBUTTONDOWN:
        for i in range(len(x_list)-1):
            cv2.line(img1, [x_list[i],y_list[i]] ,[x_list[i+1],y_list[i+1]],(0,0,255),thickness=2)
        cv2.line(img1, [x_list[-1], y_list[-1]], [x_list[0], y_list[0]], (0, 0, 255), thickness=2)
        cv2.imshow("image", img1)
    if event == cv2.EVENT_MBUTTONDOWN:
        img1 = img.copy()
        cv2.imshow("image", img1)
        x_list.clear()
        y_list.clear()


def get_coordinate_by_click(img_path):
    global img
    img = cv2.imread(img_path)  # 图片路径
    cv2.namedWindow("image", 0)  # 设置窗口标题和大小
    cv2.setMouseCallback("image", mouse)
    cv2.imshow("image", img)
    cv2.waitKey(0)
    print("x坐标:",x_list)
    print("y坐标:",y_list)
    cv2.destroyAllWindows()


if __name__ == '__main__':
    x_list=[]
    y_list=[]
    img_path = r'./figure/2/1.jpg'
    get_coordinate_by_click(img_path)

4.3 Hough变换提取直线

按照之前标定的ROI进行Hough变换,检测到的直线绘制一个绿色的蒙板。
在这里插入图片描述
在这里插入图片描述

五、核心代码

import numpy as np
import cv2
from myClass import YoloV5
from myFunction import weighted_img, draw_lines, hough_lines


if __name__ == '__main__':
    print("[INFO] 开始YoloV5模型加载")
    # YOLOV5模型配置文件(YAML格式)的路径 yolov5_yaml_path
    model = YoloV5(yolov5_yaml_path='config/yolov5s.yaml')
    print("[INFO] 完成YoloV5模型加载")
    low = 200 #Canny low
    high = 300 #Canny high
    rho = 1  # 霍夫像素单位
    theta = np.pi / 360  # 霍夫角度移动步长
    hof_threshold = 20  # 霍夫平面累加阈值threshold
    min_line_len = 10  # 线段最小长度
    max_line_gap = 20  # 最大允许断裂长度
    index = 0 #图片索引
    while True:
        index = index + 1
        # 一张一张图片进行检测按index进行索引
        path = r"./figure/1/" + str(index) + ".jpg"
        path_output = r"./out/2/" + str(index) + ".jpg"
        color_image = cv2.imread(path)
        lane_img=color_image.copy()
        edges = cv2.Canny(lane_img, low, high)
        mask = np.zeros_like(edges)
        # vertices = np.array( [[(554, 463), (733, 464), (1112, 654), (298, 671)]],dtype=np.int32)#素材2的ROI
        vertices = np.array( [[(757, 800), (1150, 800), (1556, 1064), (314, 1064)]],dtype=np.int32)#素材1的ROI
        cv2.fillPoly(mask, vertices, 255)#绿色蒙板绘制
        masked_edges = cv2.bitwise_and(edges, mask)  # 按位与
        line_image = np.zeros_like(lane_img)
        # 绘制车道线线段
        lines = hough_lines(masked_edges, rho, theta, hof_threshold, min_line_len, max_line_gap)
        draw_lines(line_image, lines, thickness=10)
        # YoloV5 目标检测
        canvas, class_id_list, xyxy_list, conf_list = model.detect(color_image)
        if xyxy_list:
            for i in range(len(xyxy_list)):
                ux = int((xyxy_list[i][0] + xyxy_list[i][2]) / 2)  # 计算像素坐标系的x
                uy = int((xyxy_list[i][1] + xyxy_list[i][3]) / 2)  # 计算像素坐标系的y
                cv2.circle(canvas, (ux, uy), 4, (255, 255, 255), 5)  # 标出中心点
                cv2.putText(canvas, str([ux, uy]), (ux + 20, uy + 10), 0, 1,
                            [225, 255, 255], thickness=2, lineType=cv2.LINE_AA)  # 标出坐标
        canvas=weighted_img(canvas, line_image)
        # 可视化部分
        cv2.namedWindow("raw", 0)
        cv2.imshow('raw',color_image)
        cv2.namedWindow("line", 0)
        cv2.imshow('line',line_image)
        cv2.namedWindow('detection', 0)
        cv2.imshow('detection', canvas)
        # cv2.imwrite(path_output, canvas)#图片保存
        key = cv2.waitKey()
        # Press esc or 'q' to close the image window
        if key & 0xFF == ord('q') or key == 27:
            cv2.destroyAllWindows()
            break

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于YOLOv5+Hough变换的目标检测和车道线检测 的相关文章

随机推荐

  • js rsa加密_Python实现RSA(jsencrypt)加密的两种方式

    RSA是一种常用加密算法 经常用在前端向后端传送密码的时候 一 通过运行rsa js文件加密 rsa js文件下载地址 https gitee com youchuanming rsa jsencrypt import urllib pur
  • 常见排序算法的js实现

    常见排序算法的js实现 冒泡排序 选择排序
  • git 笔记/常见命令/as的fetch,pull ,update project的区别/标签管理

    Git概念汇总 头 HEAD 头 HEAD HEAD类似一个 指针 指向当前活动 分支 的 最新版本 工作区 Workspace 就是在电脑里能看到的项目代码库目录 是我们搬砖的地方 在这里我们可以新增文件 修改文件内容 或删除文件 此时的
  • Java线程的5种状态及状态之间转换

    Java中的线程的生命周期大体可分为5种状态 1 新建 NEW 新创建了一个线程对象 2 可运行 RUNNABLE 线程对象创建后 其他线程 比如main线程 调用了该对象的start 方法 该状态的线程位于可运行线程池中 等待被线程调度选
  • 电子设计竞赛应该如何准备?

    全国大学生电子设计竞赛 当初我听到这个比赛的时候心中还有些胆怯 毕竟它含金量确实高 而且要想在全国去的好的名次 也确实不是一件容易的事情 但经过我大二一年的准备 我还是在自己的努力下 拿到了全国二等奖 现在都还清楚地记得但是得知我们的团队获
  • ChatGPT对高校人才培养模式的挑战与应对策略思考

    酷吗 输入指令后直接就能生成一大串代码 即使不懂相关技术也能玩转编程 这就是ChatGPT赋予你的 新能力 除了写代码 ChatGPT还能帮你执行各种五花八门的任务 AI工具如ChatGPT在行业中的广泛应用对于行业的人才结构和能力要求产生
  • 部署Vista – 第18部分:管理Windows部署服务

    原创作品 允许转载 转载时请务必以超链接形式标明文章 原始出处 作者信息和本声明 否则将追究法律责任 http iwantfly blog 51cto com 1048259 240872 介绍如何管理和配置Windows部署服务服务器 本
  • ms project 入门_Microsoft Project 2010入门

    ms project 入门 Would you like to keep your projects on track and keep track of how time and resources are used Let s take
  • React直接渲染从后台传过来的标签

    在工作中使用react 遇到需要渲染从后台获取到的标签语言 发现直接放在react中是不能解析标签语言的 解决办法如下 var content strong content strong 假设content是从接口获取到的数据 react
  • 大数据shell基础

    一 常用shell命令 1 管道命令 命令1 命令2 命令1的输入作为命令2的输入 2 抓取命令 grep命令 可以使用正则表达式来过滤 3 查找命令 find命令 选项参数 type name size perm 如果上面这个不行可以在
  • 蓝桥杯 java a组_2019年第十届蓝桥杯国赛总结(JavaA组)

    JavaA组国二 可以报销了 JA死亡之组可不是盖的 rank12的排名还是拿不到国一啊 只有五个 出成绩的一刻波澜不惊 毕竟去年有国一了不慌哈哈哈 不过对我来说这个结果还算意料之外吧 毕竟大三考研狗 这次再也不敢说蓝桥杯水了 十周年十道题
  • EMC的RS和CS和RI,CI一样吗是属于EMS 吗

    EMC Electromagnetic Compatibility 是指电子设备在电磁环境中能够正常工作 同时不对周围的其他设备和系统产生不可接受的电磁干扰的能力 在EMC设计中 RS Radiated Susceptibility 和CS
  • stm32电机驱动调试平台pid调试开发ros底盘里程计脉冲速度监测MPR

    MPRO 用于调试ros小车底盘 pid开发学学 电机驱动板反馈脉冲等数据的上位机工具 欢迎下载试用 MPRO搭载stm32单片机驱动GA370编码电机 实现PID速度调节 转向控制 实体图如下 采用杜邦线加模块设计 简单易用 可实现插拔
  • JLINK在ADS中的调试心得

    JLINK在ADS中的调试心得 分类 ARM 2010 01 03 19 39 138人阅读 评论 0 收藏 举报 分享 JLINK在ADS下调试心得 前两天一个客户用jlink在ADS来调试LPC2148总报错 这个错误我之前在调试LPC
  • 【论文精读】HumanNeRF

    目录 Abstract 1 Introduction 2 Related work Human specific rendering Neural radiance fields Human specific neural renderin
  • Java:抽象类和接口

    文章目录 抽象类 什么是抽象类 抽象类的特性 为什么会有抽象类这种东西 接口 什么是接口 接口的特性 匿名内部类 拓展 实现多个接口 接口间的继承 三个重要的接口 Comparable接口 Comparator接口 Clonable接口 浅
  • 关于 Cannot read property 'length' of null 报错的解决办法

    最近在搞前端的时候突然报了Cannot read property length of null的错 一开始都是在前端调试错 发现解决不了问题 后来发现如果你所查找的数据条数为0的时候 后端返回给前端是null 此时必然报错Cannot r
  • CityEngine三维建模几个常见问题解决方法(1)

    CityEngine被Esri收购以后 大踏步进入GIS三维建模领域 由于CityEngine独有的基于规则建模 使得GIS三维建模效率大增 不过不是规则就可以一刀切 解决所有问题的 有时我们还是要做这样或那样的一些处理才能顺利的使用规则达
  • Mysql8.0开启远程访问权限

    use mysql 登录后选择mysql数据库 select host user password from user 查看当前root对应host是否为 update user set host where user root 更新 se
  • 基于YOLOv5+Hough变换的目标检测和车道线检测

    这学期做的一个大作业 实现了对行驶过程中车辆 行人以及车道线的检测 1 B站视频演示 2 Github仓库链接 文章目录 一 实现效果 二 环境配置 三 基于YOLOv5的目标检测 四 基于Hough变换的车道线检测 4 1 前置工作 Ca