news 2026/9/11 12:59:19

轨道检测与障碍物识别:Canny+霍夫变换+YOLOv5实战解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
轨道检测与障碍物识别:Canny+霍夫变换+YOLOv5实战解析

简介:一套面向电车轨道与障碍物检测的目标检测项目,整合传统数字图像处理与YOLOv5深度学习算法,适合计算机相关专业学生、教师及开发者用于课程设计、毕业设计或算法学习。项目先采用边缘检测、透视变换、霍夫变换标注轨道并划定感兴趣区域,再借助YOLOv5模型对区域内障碍物进行实时识别与标注,白天和夜晚条件下均有较好效果,实测处理速度约为十七帧每秒。压缩包内共有六十四个文件,以配置文件、Python脚本、示例图片为主,同时包含Shell脚本、Markdown说明、Jupyter笔记本、Dockerfile等,便于环境搭建、模型配置与二次开发,整体压缩后大小仅约九百六十一千字节。已有111人学习下载。资料提供从轨道检测、区域提取到障碍物识别的完整代码管线,附有测试图片、模型配置文件和使用说明文档,代码均通过运行验证,可直接上手学习,也能够在此基础上扩展其他检测功能。

1. 轨道检测和障碍物识别,混搭不是炫技

电车轨道检测有个反直觉的事实:仅用YOLOv5端到端识别轨道,白天勉强能用,晚上几乎不可靠,因为轨道是细长线状目标,标注成本高且小目标特征弱。而传统数字图像处理里的边缘检测、霍夫变换却能稳稳锁定轨道线,代价是无法判断轨道上有什么。这套SJTU课程设计把两者串成一条流水线:先用Canny+霍夫变换求轨道线,再得到矩形ROI,最后把ROI交给YOLOv5做障碍物识别,输出帧率约17FPS。项目代码按python工程组织,含calImage、line、pipeline、detect、vedio等模块,适合做课设、毕设,也适合想搞懂目标检测预处理逻辑的工程师。它不是把两个模型堆在一起,而是让传统算法替深度模型做了一次空间注意力。

2. 从边缘检测到透视变换:轨道ROI提取与坐标系矫正

轨道检测的第一步不是跑网络,而是先搞清楚轨道在图像里的几何规律。电车轨道在画面中通常呈两条近似直线,交于灭点;只要把它们提取出来,就能框出火车驶来的方向区域。常见做法是Canny边缘检测 + 霍夫直线检测 + 透视变换。下面拆开讲。

2.1 Canny边缘检测与形态学闭运算的配合

Canny对光照敏感,但白天和夜晚的轨道边缘都有一个共同点:轨道与道床之间的灰度跳变是局部的。用Canny前先转灰度,再高斯模糊去掉细纹理。核心参数是threshold1和threshold2,过高会把夜间昏暗轨道过滤掉,过低会引入大量道砟边缘。我一般先设threshold1=50, threshold2=150,再按视频亮度上下浮动。

import cv2 import numpy as np def get_edges(frame): gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0) edges = cv2.Canny(blur, 50, 150) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3)) closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) return closed

这里Canny先给出二值边缘,再闭运算把断成一段段的轨道线连起来。闭运算的结构元用宽5高3的矩形,因为轨道在图像里是水平延展的曲线,宽度方向有轻微斜度;如果结构元太大,会把相邻两条轨道粘在一起,太小则夜间补不上断口。这个细节直接影响后续霍夫变换能不能检出完整直线。

2.2 霍夫直线检测与轨道线聚类

得到闭合边缘后,用cv2.HoughLinesP检测直线段。HoughLinesP是概率霍夫,比标准霍夫快,且输出线段端点。要特别注意minLineLength和maxLineGap两个参数:minLineLength设太短会把枕木阴影、路边护栏的短边缘也选成候选;设太长,夜间轨道边缘断续时可能检不出。实测中minLineLength设为80像素,maxLineGap设为20像素能兼顾白天和夜间。

lines = cv2.HoughLinesP(closed, rho=1, theta=np.pi/180, threshold=50, minLineLength=80, maxLineGap=20) left_lines, right_lines = [], [] if lines is not None: for line in lines: x1, y1, x2, y2 = line[0] k = (y2 - y1) / (x2 - x1 + 1e-6) if k < -0.3: left_lines.append(line[0]) elif k > 0.3: right_lines.append(line[0])

这里按斜率粗略分类:图像坐标系y轴向下,电车轨道向左远方延伸时斜率为负,向右延伸为正。之后对左右两组线段分别取最长的几条做最小二乘拟合,得到轨道直线方程。注意不能用平均斜率代替拟合,因为近处轨道在画面中占比大,远处占小,简单平均会高估远端的收敛角度。

2.3 透视变换矩阵计算与ROI掩膜生成

得到左右轨道直线后,可以计算它们在图像平面内的交点作为灭点,再结合画面底部的两个端点构成一个梯形。这个梯形是轨道区域的自然表示。但YOLOv5的输入是矩形,训练时多是正方形缩放;直接把梯形送给网络会拉伸目标比例。所以要做一个透视变换,把梯形矫正成矩形。

pts_src = np.float32([[x_left_bottom, y_bottom], [x_right_bottom, y_bottom], [x_right_top, y_top], [x_left_top, y_top]]) pts_dst = np.float32([[0, height], [width, height], [width, 0], [0, 0]]) M = cv2.getPerspectiveTransform(pts_src, pts_dst) bird_view = cv2.warpPerspective(frame, M, (width, height)) mask = np.zeros((height, width, 3), dtype=np.uint8) cv2.fillPoly(mask, [np.int32(pts_src)], (255, 255, 255))

M就是透视变换矩阵。warpPerspective把原始图像投影到一个虚拟俯视角坐标系中,后续YOLOv5的推理既可以在这个鸟瞰图里做,也可以把矩形ROI反变换回原图做。注意pts_dst的width和height应当和YOLOv5输入尺寸对齐,否则后面坐标映射时要再做一次缩放,容易出错。mask的作用是限定障碍物检测的有效范围,把轨道区域外的电线杆、行人过滤掉。

3. 基于YOLOv5的障碍物识别:模型选型与检测流程

轨道区域框出来之后,真正的目标是识别轨道上的障碍物。项目选的是YOLOv5,这里不光是会用的问题,还要知道为什么在课设里选它而不是Faster R-CNN或SSD。

3.1 选择YOLOv5s作为基础模型的原因

YOLOv5s是yolov5网络结构中最小的标准版本,参数量大约7.2M,输入640x640时单帧推理在GTX1660上大约5ms,加上前后处理能到17FPS,正好满足本项目视频流的实时需求。而Faster R-CNN在同等精度下推理速度慢一个数量级,SSD对小型障碍物(如石块、锥桶)召回率低。更重要的是YOLOv5的工程配套完善:detect.py直接支持摄像头、视频和图片,训练脚本自带数据增强,配好环境和数据集就能跑,适合课程设计周期。

障碍物类别一般定义成person、bicycle、car、truck、cone、barrier等,因为电车轨道上的障碍物多是行人或停放的车辆。如果检测目标限定在轨道范围内,类别数不超过6个时,YOLOv5s在公开COCO预训练权重上微调即可,不需要从头训练。

3.2 detect.py推理链路与参数配置

项目中的detect.py基于YOLOv5官方源码,主要改动了两个地方:一是读取视频帧后先调用pipeline.py得到ROI mask;二是把检测结果框与mask做逻辑与操作,滤除区域外框。启动推理的命令常见做法是:

python detect.py --weights best.pt --source vedio.mp4 \ --img-size 640 --conf-thres 0.45 --iou-thres 0.45 \ --device 0 --project output --exist-ok

参数含义:

  • weights:训练好的权重文件,课程设计里一般用val集上mAP最高的权重,而非最后一轮权重。
  • source:输入视频或图片路径,也可以设为0调用摄像头。
  • conf-thres:置信度阈值,过滤低置信度框。白天可设0.45,夜间会适当降到0.35,因为夜间检测框得分整体偏低。
  • iou-thres:NMS的IoU阈值,0.45是YOLOv5默认值,重叠目标多时改成0.3更保守。
  • img-size:推理尺寸,640对速度与精度平衡最好,480能提升FPS但小障碍物容易漏。

3.3 白天/夜晚样本增强与训练细节

项目要求同时处理白天和夜晚两种环境,所以训练数据不能只用白天图像。YOLOv5自带的Mosaic增强把四张图拼成一张,能增强小目标与遮挡鲁棒性;但对夜晚样本,Mosaic反而可能让夜间目标被白天背景稀释。常见做法是在数据集中按1:1混入白天与夜晚帧,然后单独关闭夜间样本的RandomPerspective,或者对夜间图做一次等宽Gamma校正。

超参数建议值说明
epochs150微调时100-200都行,看验证损失是否收敛
batch-size16取决于显存,8G显存建议8
lr00.01预训练权重微调用0.01,随机初始化用0.1
mosaic0.5概率0.5,夜间数据占比高时调低
fliplr0.25轨道目标左/右翻转仍合理,但太高会破坏灭点方向

这里特别要提一句:yolov5训练自己的数据集时,一定要确认data.yaml里的nc和names与实际标注一致。项目中常见错误是标注类别索引从0开始,但训练时写了从1开始,导致所有标签偏移一位,检测框全部错位。检查方法很简单:训练前运行python train.py --data data.yaml --weights yolov5s.pt,观察第一个epoch的loss是否有明显下降,若震荡不降,多半是标签问题。

4. 轨道与障碍物结果融合:坐标映射与性能优化

模型单独跑通只是第一步。实际视频里,YOLOv5输出的是640x640坐标系的矩形框,必须与原始画面坐标对齐,同时还要受ROI约束。这个融合模块会决定检测结果看起来“准不准”。

4.1 ROI区域映射与置信度过滤

如果推理在原始图像上进行,那么检测框坐标就是原始坐标,直接用cv2.pointPolygonTest判断框底边中点是否落在ROI多边形内。如果推理在鸟瞰图里进行,则需要用透视变换矩阵的逆矩阵把检测框四个角点映射回原图,再做同一个判断。

pts_src = trailer_roi # 梯形ROI四个点,由line.py输出 def in_roi(box, roi_pts): cx = (box[0] + box[2]) / 2 cy = (box[1] + box[3]) / 2 return cv2.pointPolygonTest(roi_pts, (cx, cy), False) >= 0 filtered = [b for b in detections if in_roi(b, pts_src)]

这里用框底边中心点而不是整个框来判断,是因为障碍物与轨道的接触点通常在地面附近,如果框的上半部分(如行人头部)在ROI外但脚在ROI内,应该保留;反过来,如果底边中心在ROI外,即便框的上边缘压线,也应该剔除。用框的中心点会误留很多路旁行人,实测漏检和误检都会上升。注意pointPolygonTest的第三个参数设置成False,表示只返回点在多边形内部还是外部,不加距离计算,速度最快。

4.2 帧间处理与FPS优化策略

17FPS来自几个取舍。第一是推理分辨率,本项目最终选择640但关闭了类别输出;第二是启用半精度推理,detect.py中加一句model.half(),在GTX 16系以上显卡上能把推理延迟降低约30%;第三是视频解码用cv2.VideoCapture直接读,不做逐帧缩放,而是只在送入模型前resize。这三个改动组合常见,效果稳定。

另一个更激进的方法是跳帧:每两帧只对一帧做YOLOv5检测,不做检测的帧直接沿用上一帧的检测结果,配合简单的KCF跟踪,能把总体帧率提高到25FPS。课程设计答辩时可以用这个方案展示“实时效果”,但要注意评估指标里要注明实际推理帧率是17FPS,跳帧属于后处理优化。

4.3 常见误检分析:路灯、信号灯与反光

夜间场景中,YOLOv5容易把亮度集中的路灯灯头、信号灯和轨道反光区域当作障碍物。原因很简单:conf阈值降低后,这些高对比目标与障碍物特征接近。处理方式不只有调阈值:

  • 把ROI底边中心点的判断改成“地面接触点”,压线信息比框中心更可靠。
  • 对检测类别做先验限制:比如轨道内出现“car”且位置固定不动,连续30帧没有位移,就降低其置信度并标记为静态物体,不作为紧急障碍物告警。
  • 对反光带,可以在预处理里增加一个对比度归一化,让反光区域与障碍物的纹理差别更大。

注意不能只靠颜色过滤,因为夜间列车灯光会把轨道照射成亮黄色,与警告锥桶颜色接近。

5. 从课程设计到落地:验证指标与调参技巧

课设不能只停在“能跑”,还要让评估结果可复现。这里分享验证指标和调参的具体做法,这两项做扎实了,答辩才能从“效果较好”变成“结果可信”。

5.1 用mAP@0.5和漏检率评估检测效果

课程设计里不能只说“效果较好”,需要给量化指标。常见做法是在标注好的测试视频帧上统计mAP@0.5。这里给出一个轻量级评估脚本:

import torch from pathlib import Path from utils.metrics import ap_per_class def evaluate(dataloader, model, iou_thres=0.5): stats = [] for images, targets in dataloader: preds = model(images)[0] # 将preds转为(x1y1x2y2, conf, cls)格式 for batch_idx, pred in enumerate(preds): target = targets[targets[:, 0] == batch_idx] stats.append((pred.cpu(), target.cpu())) # 调用YOLOv5官方metrics计算AP p, r, ap, f1, _ = ap_per_class(*stats, plot=False, save_dir=Path('.')) return ap.mean(), r.mean(), p.mean()

这个脚本直接用YOLOv5源码里的ap_per_class,省去自己实现IoU匹配。测试时要注意每类样本数量不能太少,至少每个类别超过50个真实框,否则mAP做出来不稳定。除了mAP@0.5,还要统计漏检率:针对视频里连续出现的同一障碍物,只要在连续10帧中有一帧没检测到,就算一次漏检。这个指标对轨道障碍物比mAP更敏感,因为行人一旦漏检一帧,后续跟踪就会丢失。

5.2 超参数调整优先级与踩坑记录

调参与其说按经验,不如按优先级排查。我一般会这样收敛:

  1. 先固定conf-thres=0.4,看无效检测框是太多还是太少:太多说明类别混淆严重,应回头检查数据集标注;太少则明显漏检,说明模型欠拟合或阈值不合适。
  2. 再看NMS的iou-thres:检测框重叠度高时降低到0.3,不要盲目用默认值。
  3. 最后才动模型超参数,比如学习率从0.01减到0.005,用余弦退火观察loss曲线是否平滑。

整个过程要记录每个版本在验证集上的mAP和漏检率,而不是只看demo视频。

踩坑记录中最常见的有几个:

  • OpenCV版本影响透视变换结果:OpenCV 4.5以上对坐标精度有变化,课设中最好固定python=3.8, opencv-python=4.5.5.64。
  • 中文路径问题:视频文件名或图片路径含中文时,cv2.VideoCapture会读取失败,detect.py报错找不到文件。把工程路径统一为英文小写。
  • 权重文件路径:.pt文件是相对路径打包的,把best.pt移到其他目录后,要同步复制模型对应的yaml文件,否则会报yaml not found。
  • 最容易被忽略的是eval期间的半精度开关:训练时用了model.half(),测试时如果忘记调成float32,会得到精度降低的框,特别是小目标上。

还有一个实用技巧:把pipeline.py中的轨道检测过程单独抽出来,输出一张可视化图,叠加Canny边缘和轨道直线。这样在答辩时可以清楚展示“数字图像处理”部分的中间结果,说明算法不黑盒。检测模型只在ROI中有意义,轨道线的质量决定了障碍物检测的上限。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 12:56:41

序列绑定:从算法到UI、网络与三维创作的本质与排查

不用急着翻开任何一本算法书或者框架文档。先说说我怎么注意到"序列绑定"这个问题的&#xff1a;有天晚上我排查一个WPF界面按钮点了没反应的问题&#xff0c;查了两小时&#xff0c;最后定位到是Command绑定的CanExecute没有触发刷新&#xff1b;关掉调试器刷手机&a…

作者头像 李华
网站建设 2026/9/11 12:56:02

OpenProject 快速上手指南:免费的开源项目管理软件

OpenProject 快速上手指南&#xff1a;免费的开源项目管理软件 【免费下载链接】openproject OpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue …

作者头像 李华
网站建设 2026/9/11 12:55:40

Android音频用途管理:AudioAttributes与getUsage详解

1. Android音频用途管理基础 在Android音频系统中&#xff0c;AudioAttributes是一个核心类&#xff0c;它定义了音频流的属性和用途。这个类在API 21(Android 5.0)中被引入&#xff0c;用于替代旧的AudioManager中的流类型(STREAM_MUSIC, STREAM_RING等)系统。AudioAttributes…

作者头像 李华
网站建设 2026/9/11 12:54:55

Android车载串口开发实战:UART、RS485配置与MODBUS通信

1. 项目概述&#xff1a;为什么车载 Android 设备必须啃下串口这根硬骨头&#xff1f;在车载电子系统里&#xff0c;UART 不是教科书里的一个抽象概念&#xff0c;而是实实在在的“神经末梢”——它连着倒车雷达的测距模块、连着车身控制单元&#xff08;BCM&#xff09;的灯光…

作者头像 李华
网站建设 2026/9/11 12:54:22

Midscene Chrome扩展:5分钟搭好你的浏览器自动化流水线

Midscene Chrome扩展&#xff1a;5分钟搭好你的浏览器自动化流水线 【免费下载链接】midscene GUI Agent for E2E Testing 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene 上周二我手动逐页核对页面状态核到昏头&#xff0c;换上 Midscene Chrome 扩展后&…

作者头像 李华
网站建设 2026/9/11 12:53:50

OpenCV人脸检测高分项目实战:Haar+LBP混合检测与工程化落地

简介&#xff1a;本资源是一套基于Python与OpenCV实现的人脸识别高分毕业设计项目&#xff0c;面向计算机相关专业本科生及课程设计、期末大作业、毕业设计阶段的学习者&#xff0c;解决从人脸检测、特征提取到身份识别的完整技术实践需求。压缩包共35个文件&#xff0c;含9个核…

作者头像 李华