东莞网站建设的方案,销售网站建设的会计分录,网站怎样建设才叫人性化,南昌做网站优化哪家好基于YOLOv8的车辆过线计数与检测区域设置
在城市交通管理、智能安防和车流监控等实际场景中#xff0c;对道路上行驶车辆进行自动统计是一项基础但关键的任务。传统的人工计数方式效率低、成本高#xff0c;而基于视频分析的自动化方案正成为主流。最近我尝试使用 YOLOv8 搭配…基于YOLOv8的车辆过线计数与检测区域设置在城市交通管理、智能安防和车流监控等实际场景中对道路上行驶车辆进行自动统计是一项基础但关键的任务。传统的人工计数方式效率低、成本高而基于视频分析的自动化方案正成为主流。最近我尝试使用 YOLOv8 搭配目标追踪算法实现一个轻量级、可复现的车辆过线计数系统整个过程无需复杂环境配置也不依赖收费框架所有代码均可本地运行。项目基于 Ultralytics 官方提供的YOLO-V8 Docker 镜像该镜像已预装 PyTorch 2.2.1 CUDA 12.1 Ultralytics 库支持 Ubuntu 20.04/22.04 系统开箱即用。如果你已有满足python3.8和torch2.2.1的环境也可以跳过容器部署直接进入开发阶段。快速启动两种接入方式使用 Jupyter Lab 进行交互式开发容器启动后默认会开启 Jupyter Lab 服务端口 8888通过浏览器访问http://your-server-ip:8888首次登录需输入 token可在容器日志中查看后续建议设置密码以方便长期使用。进入/root/ultralytics目录即可开始编码from ultralytics import YOLO # 加载COCO预训练模型 model YOLO(yolov8n.pt) # 查看模型结构可选 model.info() # 对图片推理 results model(path/to/car.jpg) results[0].show() # 显示带框结果图你还可以上传自己的测试视频如car.mp4用于后续功能验证。这种方式适合快速原型验证和教学演示尤其适合初学者上手。使用 SSH 登录进行深度定制若需要修改源码或调试底层逻辑推荐使用 SSH 登录容器内部ssh rootyour-server-ip -p 2222默认用户名为root密码根据初始化脚本设定。登录成功后进入项目目录cd /root/ultralytics此时可以自由编辑.py文件、运行命令行脚本或集成第三方工具灵活性更高。对于需要自定义检测流程、扩展绘图功能或集成业务系统的开发者来说这是更合适的开发模式。初步验证YOLOv8 推理能力测试在正式开发前先确认基础检测功能是否正常工作。图片检测示例from ultralytics import YOLO model YOLO(yolov8n.pt) results model(path/to/car.jpg) results[0].save(output_car.jpg) # 保存标注后的图像视频实时检测results model.predict( sourcecar.mp4, showTrue, # 实时显示窗口 saveTrue, # 保存输出视频 conf0.5, # 置信度阈值 classes[2], # 只检测 car 类别COCO中ID2 )输出视频将自动保存至runs/detect/predict/路径下。这一步不仅能验证模型可用性也能帮助我们观察原始画面中的车辆分布情况为后续设置检测区域提供参考。设置固定检测区域ROI为了提升检测准确率并减少边缘干扰例如行人、背景晃动我们应限定一个感兴趣区域Region of Interest, ROI仅在此范围内执行目标检测。修改预处理函数以应用遮罩文件路径ultralytics/engine/predictor.py我们在preprocess方法中添加图像遮罩逻辑import cv2 import numpy as np def preprocess(self, im): 在原始图像上应用ROI遮罩后再送入模型。 Args: im (list[np.ndarray]): 输入图像列表 [(H, W, C)]。 # 定义ROI坐标左上x, y右下x, y left, upper, right, lower 0, 165, 640, 265 # 根据实际视频调整 masked_images [] for image in im: height, width image.shape[:2] mask np.zeros((height, width), dtypenp.uint8) cv2.rectangle(mask, (left, upper), (right, lower), 255, thickness-1) masked_image cv2.bitwise_and(image, image, maskmask) cv2.rectangle(image, (left, upper), (right, lower), (0, 255, 0), 2) # 绘制绿色边框 masked_images.append(masked_image) not_tensor not isinstance(masked_images, torch.Tensor) if not_tensor: masked_images np.stack(self.pre_transform(masked_images)) masked_images masked_images[..., ::-1].transpose((0, 3, 1, 2)) # HWC - CHW masked_images np.ascontiguousarray(masked_images) masked_images torch.from_numpy(masked_images) masked_images masked_images.to(self.device) masked_images masked_images.half() if self.model.fp16 else masked_images.float() if not_tensor: masked_images / 255.0 return masked_images说明- 使用 OpenCV 创建矩形掩膜非 ROI 区域像素被清零- 原图上绘制绿色矩形便于可视化检测范围- 所有后续推理均只关注该区域内目标有效降低误检率。添加中间计数线与状态显示要在检测区域内判断车辆是否“过线”我们需要画一条水平线作为基准并在画面上动态显示统计数据。参数传递机制设计1在track.py中添加命令行参数parser.add_argument(--hidecls, actionstore_true, help不显示类别标签) parser.add_argument(--draw-line, actionstore_true, help绘制中间计数线)2在BasePredictor.__init__中接收参数self.hidecls args.hidecls self.whereline None # 存储计数线起点和终点 self.numlabel count: 0 # 显示文本3在preprocess中设置计数线位置# 计数线位于ROI垂直中点 self.whereline [ (0, int(upper (lower - upper) / 2)), (width, int(upper (lower - upper) / 2)) ]扩展绘图工具类 Annotator文件路径ultralytics/utils/plotting.py向Annotator类添加两个辅助方法def draw_line(self, pt1, pt2, color(0, 255, 255), thickness4): 绘制黄色计数线 cv2.line(self.im, pt1, pt2, colorcolor, thicknessthickness) def put_text(self, text, pos, scale1.5, color(0, 0, 255), thickness3): 在指定位置写文本 cv2.putText(self.im, text, pos, cv2.FONT_HERSHEY_SIMPLEX, scale, color, thickness)修改Results.plot()方法以支持新参数文件路径ultralytics/engine/results.py更新plot()方法签名并加入绘图逻辑def plot( self, ... wherelineNone, numlabelNone, hideclsFalse, **kwargs ): annotator Annotator(...) if pred_boxes and show_boxes: for d in reversed(pred_boxes): c, conf int(d.cls), float(d.conf) name names[c] if not hidecls else label f{name} {conf:.2f} if conf and not hidecls else name annotator.box_label(d.xyxy.squeeze(), label, colorcolors(c, True)) # 绘制中心点用于轨迹追踪 xywh d.xywh.int().cpu().tolist()[0] midpoint (int(xywh[0]), int(xywh[1])) cv2.circle(annotator.im, midpoint, radius5, color(0, 0, 0), thickness-1) # 绘制计数线 if whereline is not None: annotator.draw_line(whereline[0], whereline[1]) # 显示统计信息 if numlabel is not None: annotator.put_text(numlabel, (50, 50)) return annotator.result()实现车辆过线计数逻辑核心思路是利用目标追踪 ID 和 bbox 中心点的历史轨迹判断其运动路径是否穿越计数线并结合移动方向区分“上行”与“下行”。添加辅助函数至BasePredictorimport math from collections import deque, defaultdict def tlbr_midpoint(self, box): 计算边界框中心点 minX, minY, maxX, maxY box return (int((minX maxX) / 2), int((minY maxY) / 2)) def ccw(self, A, B, C): 判断三点是否逆时针排列 return (C[1] - A[1]) * (B[0] - A[0]) (B[1] - A[1]) * (C[0] - A[0]) def intersect(self, A, B, C, D): 判断线段AB与CD是否相交 return self.ccw(A, C, D) ! self.ccw(B, C, D) and self.ccw(A, B, C) ! self.ccw(A, B, D) def vector_angle(self, curr_pt, prev_pt): 计算移动向量的角度相对于x轴 dx curr_pt[0] - prev_pt[0] dy curr_pt[1] - prev_pt[1] return math.degrees(math.atan2(dy, dx))在stream_inference中集成计数逻辑在主循环开始前初始化全局变量# 初始化路径缓存与计数器 self.paths defaultdict(lambda: deque(maxlen2)) self.up_count 0 self.down_count 0然后在每帧处理中加入判断逻辑for i in range(n): self.seen 1 p, im0 path[i], im0s[i].copy() det self.results[i].boxes.data.cpu().numpy() if len(det) 0: continue for *xyxy, conf, cls_id, track_id in det: track_id int(track_id) cls_id int(cls_id) if cls_id ! 2: # 仅统计 car continue midpoint self.tlbr_midpoint(xyxy) if track_id not in self.paths: self.paths[track_id].append(midpoint) self.paths[track_id].append(midpoint) else: self.paths[track_id].append(midpoint) if len(self.paths[track_id]) 2: continue prev_point self.paths[track_id][-2] curr_point self.paths[track_id][-1] line_start, line_end self.whereline # 判断是否穿越计数线 if self.intersect(prev_point, curr_point, line_start, line_end): angle self.vector_angle(curr_point, prev_point) if angle 0 and abs(angle) 30: # 向右上方 → 上行 self.up_count 1 elif angle 0 and abs(angle) 30: # 向右下方 → 下行 self.down_count 1 # 更新显示文本 total self.up_count self.down_count self.numlabel fTotal: {total} | Up: {self.up_count} | Down: {self.down_count}确保绘图参数正确传入在write_results或主流程中调用plot时传参plot_args { hidecls: self.args.hidecls, whereline: self.whereline, numlabel: self.numlabel, } self.plotted_img result.plot(**plot_args)这样就能实现实时渲染计数线与统计信息。完整调用命令示例python track.py \ --source car.mp4 \ --yolo-model yolov8n.pt \ --tracking-method bytetrack \ --classes 2 \ --hidecls \ --draw-line \ --save \ --device 0 参数说明---classes 2仅检测车辆COCO 数据集中 car 类别 ID 为 2---hidecls隐藏类别标签使画面更简洁---draw-line启用计数线与数据展示---tracking-method bytetrack使用 ByteTrack 提升追踪稳定性避免 ID 切换导致重复计数。效果展示与优化方向最终输出视频包含以下元素- ✅ 绿色矩形框标出检测区域ROI- ✅ 黄色横线作为计数基准线- ✅ 左上角实时显示总数量及上下行统计- ✅ 每辆车中心有黑色圆点辅助轨迹观察。进一步优化建议1.多区域支持扩展为多个 ROI 多条计数线适用于十字路口或多车道场景2.分类计数分别统计 car/truck/bus 等不同类型车辆3.流量报警机制当单位时间车流量超过阈值时触发告警4.Web 可视化平台结合 Flask/FastAPI 构建前端监控界面支持远程查看与历史回放5.性能调优改用yolov8s或yolov8m提升小目标检测精度或使用 TensorRT 加速推理。这种基于 YOLOv8 和几何判断的轻量级解决方案不仅实现了稳定可靠的车辆过线计数还具备良好的可移植性和扩展性。整个流程依托官方 Docker 镜像避免了繁琐的环境配置特别适合科研验证、教学演示以及中小型项目落地。随着边缘计算设备如 Jetson、瑞芯微的普及这类方案将在智慧城市、园区管理和交通疏导中发挥更大价值。