news 2026/9/9 12:57:25

Ultralytics 停车管理解决方案源码级解析:ParkingPtsSelection 与 ParkingManagement

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ultralytics 停车管理解决方案源码级解析:ParkingPtsSelection 与 ParkingManagement

Ultralytics 停车管理解决方案源码级解析:ParkingPtsSelection 与 ParkingManagement

【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics

本文围绕 Ultralytics 仓库中 docs/en/reference/solutions/parking_management.md 所定义的parking_management模块展开,系统讲解其两个核心类——用于车位标注的ParkingPtsSelection与用于实时车位占用监控的ParkingManagement。文章覆盖类的职责划分、GUI 标注工具的使用方式、车位区域 JSON 文件格式、完整的 Python/CLI 接入流程、全部可配置参数,以及process()背后的跟踪与点包含判定原理。读完本文,你将具备从"标注车位"到"实时输出占用/空闲统计"的端到端搭建能力,并理解其底层实现机制。

一、模块定位:一条完整的停车监控链路

在 Ultralytics 的 Solutions 组件体系中,parking_management模块负责"基于视频流的停车位占用监控"。它与传统检测方案的最大区别在于:车位布局通过 JSON 文件预定义,运行时不再依赖检测框与车位的一一匹配,而是用跟踪到的车辆中心点去判定其是否落入某个车位多边形。

模块被集中实现在 ultralytics/solutions/parking_management.py,并已在 ultralytics/solutions/init.py 中导出ParkingManagementParkingPtsSelection,因此可通过from ultralytics import solutions直接使用。该模块对外提供两个职责完全分离的类:

职责运行形态
ParkingPtsSelection图形化标注车位:上传图片、鼠标点选多边形、保存 JSONTkinter 桌面 GUI,需要显示环境
ParkingManagement实时监控车位:模型跟踪车辆并判断车位占用状态继承BaseSolution,逐帧process()

其中ParkingPtsSelection继承object,是一个独立 GUI 工具;ParkingManagement则继承 ultralytics/solutions/solutions.py 中的BaseSolution,复用其模型加载、跟踪、绘图等通用能力。从类层级与__init__.py的导出可见,仓库把"标注阶段"与"监控阶段"拆成了两个互相独立的组件,二者通过 JSON 文件衔接,这正是该方案可迁移、可复用的关键设计。

二、ParkingPtsSelection:可视化车位标注工具

在车位上拉取准确多边形是整个系统中最耗时、最容易出错的环节,仓库因此提供了图形化的ParkingPtsSelection。根据其类 docstring(parking_management.py),该工具支持上传图片、逐点点击定义停车区域并将结果写入 JSON 文件。

2.1 环境前置条件

ParkingPtsSelection依赖tkinter(GUI)、PIL/Pillow(图像加载与缩放)以及可用的图形显示环境。构造函数在启动时会做两类检查:

  1. Tkinter 可用性检查:若import tkinter失败,会按操作系统给出安装建议并直接返回(parking_management.py):

    • Linux(Debian/Ubuntu):sudo apt install python3-tk;Fedora:sudo dnf install python3-tkinter;Arch:sudo pacman -S tk
    • Windows:重新安装 Python 并在Optional Features中勾选tcl/tk and IDLE
    • macOS:重新安装带 Tk 的 Python 或brew install python-tk
  2. 显示环境检查:调用check_imshow(warn=True),若处于无显示器(如纯服务器、CI)环境,则无法启动 GUI。

2.2 交互流程与内部方法

工具启动后弹出标题为 "Ultralytics Parking Zones Points Selector" 的主窗口,顶部有三个按钮:Upload ImageRemove Last Bounding BoxSave(parking_management.py)。其核心成员与交互对应如下:

成员类型说明
rg_datalist[list[tuple[int,int]]]已确认的车位框集合,每个框由 4 个点构成
current_boxlist[tuple[int,int]]正在绘制的当前框的临时点集
imgw/imghint原始图片宽高,用于坐标缩放
canvas_max_width/canvas_max_heightint画布上限,默认1280 × 720

各按钮与方法一一对应:

  • upload_image():弹窗选择*.png *.jpg *.jpeg图片,按宽高比将图片缩放适配到画布后显示,并绑定鼠标左键事件on_canvas_click
  • on_canvas_click():每点击一次向current_box追加一个点并画一个红色圆点标记;当点满4 个时,该框被写入rg_data并通过draw_box()用蓝色折线闭合连接成多边形,然后清空current_box继续下一个车位;
  • remove_last_bounding_box():撤销最近一次确认的车位框并调用redraw_canvas()重绘(无框可删时弹出警告);
  • redraw_canvas():清空画布后重贴底图并重画所有已保存框;
  • save_to_json():计算缩放比例后把所有框写入bounding_boxes.json

2.3 保存时的坐标缩放与 JSON 格式

由于标注发生在缩放后的画布上,而推理输入是原始分辨率帧,save_to_json()会在保存时做坐标还原(parking_management.py):

scale_w, scale_h = self.imgw / self.canvas.winfo_width(), self.imgh / self.canvas.winfo_height() data = [{"points": [(int(x * scale_w), int(y * scale_h)) for x, y in box]} for box in self.rg_data]

即把画布坐标乘以原始图宽/画布宽原始图高/画布高还原为图像原分辨率坐标。最终写入工作目录下固定文件名的bounding_boxes.json,内容形如:

[ { "points": [ [334, 267], [608, 259], [613, 424], [330, 431] ] }, { "points": [ [12, 58], [260, 52], [262, 206], [10, 209] ] } ]

每个元素是一个车位,points是 4 个[x, y]角点。该结构正是ParkingManagement运行时读取同一份 JSON 的依据,两个类由此在数据层面完成了衔接。

三、ParkingManagement:实时车位占用监控核心类

ParkingManagement继承BaseSolution,类 docstring(parking_management.py)给出最小使用示例:

from ultralytics.solutions import ParkingManagement parking_manager = ParkingManagement(model="yolo26n.pt", json_file="parking_regions.json") print(f"Occupied spaces: {parking_manager.pr_info['Occupancy']}") print(f"Available spaces: {parking_manager.pr_info['Available']}")

3.1 初始化:JSON 参数强制校验

构造函数(parking_management.py)在调用super().__init__(**kwargs)完成通用配置合并后,专门处理车位数据:

self.json_file = self.CFG["json_file"] if not self.json_file: LOGGER.warning("ParkingManagement requires `json_file` with parking region coordinates.") raise ValueError("❌ JSON file path cannot be empty.") with open(self.json_file, encoding="utf-8") as f: self.json = json.load(f)

json_file是必填参数:缺省时直接抛ValueError终止初始化,这是模块与其它 Solutions(多数以region传区域)最大的不同——车位多边形必须来自外部 JSON。同时构造函数初始化统计字典与三类可视化颜色(BGR):

属性语义
pr_info{"Occupancy": 0, "Available": 0}占用数 / 可用数统计
arc(0, 0, 255)可用车位绘制颜色(BGR 红)
occ(0, 255, 0)已占车位绘制颜色(BGR 绿)
dc(255, 0, 189)检测目标中心点颜色(BGR 品红,当前用于物体标签标注)

3.2 可配置参数总表

ParkingManagement的配置统一由 ultralytics/solutions/config.py 的SolutionConfigdataclass 承接,BaseSolution会把用户 kwargs 合并进CFG(solutions.py)。以下是与该方案直接相关的参数:

Argument类型默认值说明
modelstrNone(实际回退yolo26n.ptYOLO 模型文件路径,支持检测、OBB 等模型
json_filestrNone必填,包含所有车位坐标数据的 JSON 文件路径
line_widthint2标注线宽,同时影响框/标签/统计信息绘制
verboseboolTrue是否打印逐帧日志(输入尺寸、类别计数、耗时)

方案底层走的是track 模式(见 4.2 节),因此可透传下列跟踪参数:

Argument类型默认值说明
trackerstr'botsort.yaml'跟踪算法,内置botsort.yamlbytetrack.yamlocsort.yamldeepocsort.yamlfasttrack.yamltracktrack.yaml
conffloat0.25检测置信度阈值,调低可召回更多目标但易混入误检
ioufloat0.7重叠检测框 NMS 的 IoU 阈值
classeslistNone类别过滤,如classes=[2, 7]只跟踪指定类(车辆)
devicestrNone推理设备,如cpucuda:00

此外支持可视化参数show(默认False,置True时在窗口中实时展示结果帧)。方案也接受imgsz(推理输入尺寸,默认640)等SolutionConfig通用参数。

四、完整实战流程:从标注到实时监控

完整的接入链路在 docs/en/guides/parking-management.md 中有配套讲解,共四步。

4.1 Step 1-3:获取帧并使用标注工具生成 JSON

首先从待管理的视频/相机流中截取一帧作为底图(俯视或正对停车场的机位效果最佳),随后启动标注 GUI:

from ultralytics import solutions solutions.ParkingPtsSelection()

在弹出的窗口中点击Upload Image选择截取的帧,用鼠标依次点击车位四角(每满 4 点自动生成一个蓝色框),逐个框选全部车位后点击Save。工具会将缩放还原后的坐标写入当前工作目录的bounding_boxes.json——这正是后续监控脚本默认读取的文件名。

4.2 Step 4:运行实时监控

Python 方式

ultralytics/solutions/parking_management.py 的process(im0)处理单帧,下面的完整脚本演示读取视频、逐帧处理并写出带标注的新视频:

import cv2 from ultralytics import solutions # 视频读取 cap = cv2.VideoCapture("path/to/video.mp4") assert cap.isOpened(), "Error reading video file" # 视频写出 w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) video_writer = cv2.VideoWriter("parking management.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # 初始化停车管理对象 parkingmanager = solutions.ParkingManagement( model="yolo26n.pt", # 模型文件路径 json_file="bounding_boxes.json", # 车位标注文件路径 ) while cap.isOpened(): ret, im0 = cap.read() if not ret: break results = parkingmanager(im0) # 传入单帧,返回 SolutionResults video_writer.write(results.plot_im) # 写入处理后的帧 cap.release() video_writer.release() cv2.destroyAllWindows()

调用parkingmanager(im0)会经由BaseSolution.__call__(solutions.py)自动为结果补充speed计时字段并执行verbose日志。返回的SolutionResults(solutions.py)在本方案中填充以下字段:

字段含义
plot_im带标注的处理后图像(可直接写视频/展示)
filled_slots已占用车位数
available_slots空闲车位数
total_tracks当帧跟踪到的目标总数
speed{"track": ...ms, "solution": ...ms}性能计时(由__call__注入)
CLI 方式

标注完成后,可用 Solutions CLI 免写代码运行:

yolo solutions parking source="path/to/video.mp4" json_file="bounding_boxes.json" show=True

注意:必须先通过ParkingPtsSelection()生成车位标注 JSON,再将其路径传给 CLI 的json_file参数。

CLI 下show=True会弹出实时可视化窗口,按q键关闭(对应 solutions.py 中display_output的实现)。

五、process() 运行原理:跟踪、点包含判定与可视化

要理解并正确使用该方案,需要拆解process()(parking_management.py)的四个阶段。

5.1 阶段一:跟踪而非纯检测

self.extract_tracks(im0) # 提取跟踪目标

extract_tracks(solutions.py)内部调用self.model.track(source=im0, persist=True, ...),并把结果区分为两种数据形态:

  • 检测模型:跟踪数据取tracks.boxes,框为轴对齐的[x1, y1, x2, y2]
  • OBB 旋转框模型:跟踪数据取tracks.obb,框为(4, 2)xyxyxyxy四角点。

随后boxesclsstrack_idsconfs被同步提取。get_enclosing_box静态方法(solutions.py)负责把上述两种格式统一归一化为轴对齐[x1, y1, x2, y2],从而兼容旋转框模型。

5.2 阶段二:逐车位做"中心点入多边形"判定

available_slots, occupied_slots = len(self.json), 0 for region in self.json: region_polygon = np.array(region["points"], dtype=np.int32).reshape((-1, 1, 2)) region_occupied = False for box, cls in zip(self.boxes, self.clss): x0, y0, x1, y1 = self.get_enclosing_box(box) xc, yc = int((x0 + x1) / 2), int((y0 + y1) / 2) inside_distance = cv2.pointPolygonTest(region_polygon, (xc, yc), False) if inside_distance >= 0: region_occupied = True break

实现细节非常直观:每个车位多边形由 JSON 中region["points"]的 4 个角点按(N, 1, 2)形状构造;对每个跟踪框求几何中心(xc, yc),再用 OpenCV 的cv2.pointPolygonTest(..., False)判断中心点与多边形位置关系——返回值≥ 0 即视为中心在车位内(等于 0 表示恰好落在边界上),此时该车位标记为已占用并跳出内层循环。这一"中心点判定"策略计算开销极低,适合单路视频流的实时处理。

5.3 阶段三:可视化与统计更新

被判定占用的目标会在图像上绘制类别标签(调用annotator.display_objects_labels,颜色来自dc与文本色(104, 31, 17)/(255, 255, 255))。随后每个车位用cv2.polylines勾勒轮廓,占用车位画绿色、空闲车位画红色

cv2.polylines(im0, [region_polygon], isClosed=True, color=self.occ if region_occupied else self.arc, thickness=2)

帧末更新统计字典并叠加实时读数:

self.pr_info["Occupancy"], self.pr_info["Available"] = occupied_slots, available_slots annotator.display_analytics(im0, self.pr_info, (104, 31, 17), (255, 255, 255), 10)

5.4 阶段四:返回结构化结果

处理完成后,通过display_output(在show=True且有显示环境时弹窗展示)并以SolutionResults封装返回plot_imfilled_slotsavailable_slotstotal_tracks。值得注意total_trackslen(self.track_ids)计算,反映的是跟踪目标总数而非"在场车辆数",二者在单车辆被误分为多轨迹时可能不一致。

六、测试与稳定性保障

该模块在仓库测试中覆盖度较好,tests/test_solutions.py 提供了三层验证:

  1. 端到端视频测试test_solution参数化矩阵中注册了ParkingManager用例(test_solutions.py),使用专用车位模型与车位 JSON 资产、imgsz=320逐帧跑完整视频,验证初始化与推理不崩溃。注释还特别说明该用例使用yolo26n-obb.pt与停车视频素材,用于覆盖OBB 旋转框路径——因为get_enclosing_box需处理四角点格式;
  2. 单帧崩溃回归测试(test_solutions.py):对ParkingManagement等方案只处理parking_video的首帧,快速暴露 "json 文件解析 / 多边形构造" 类崩溃点;
  3. 缺参优雅失败测试test_parking_json_none(test_solutions.py)专门验证缺省 JSON 时抛错的预期行为,与构造函数中raise ValueError的实现互相印证。

这些测试表明:只要提供格式正确的json_file与任一款可跟踪的 YOLO 模型(检测或 OBB),模块即可稳定运转;而自定义场景的主要工作量集中在车位标注与模型类别选择上。

七、FAQ 与常见调优

如何为自有停车场适配布局?最关键的参数是json_file——用ParkingPtsSelection为你的俯视画面重新框选车位并另存 JSON 即可切换新布局,其余代码零改动。

如何只统计车辆而不是行人/自行车?通过classes参数按类别索引过滤,例如 COCO 数据集中轿车/卡车等车辆类索引传入classes=[2, 5, 7]附近取值;也可conf提升到更高阈值剔除虚检,或切换到更合适的tracker

监控画面有抖动、计数不稳定怎么办?因为判定依赖跨帧一致的目标身份,跟踪稳定性直接影响计数,可从三方面入手:保持persist=True的连续帧输入、选用botsort.yaml/deepocsort.yaml等对短遮挡更鲁棒的跟踪器、必要时提升输入分辨率imgsz以改善远距离小目标检测。

运行时报 "JSON file path cannot be empty"?表明未传json_file,属预期强校验(参考 parking_management.py),检查构造参数拼写并确认 JSON 路径存在即可。

返回结果的字段与处理帧如何取用?results.plot_im直接用于cv2.VideoWriter写出或cv2.imshow展示;results.filled_slots/results.available_slots可进一步接入业务侧的大屏看板或日志系统;results.total_tracks表示当前跟踪目标数。若把结果叠加输出到终端,可打印(或自定义接入)与监控数据,形成完整的上报闭环。

【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

超声相控阵聚焦仿真:COMSOL频域参数化模型实现与光声应用拓展

通常来说,超声相控阵聚焦仿真不算一个特别冷门的领域,但网上能直接跑通的完整参数化模型并不多。前阵子正好有个项目需要评估相控阵在不同焦点深度、不同阵元数下的聚焦声场,我用COMSOL搭了一个频域求解的有限元模型,不需要每次改…

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

Opencode本地AI编程代理安装与故障排查指南

1. 项目概述:Opencode 不是“开源代码”的泛称,而是一个真实存在的 AI 编程代理工具最近在开发者社区里,“opencode”这个词被反复提起,但很多人一搜就懵——它既不是 Linux 内核里的某个模块,也不是 GitHub 上某个明星…

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

ECharts 世界地图实战:从 GeoJSON 注册到 visualMap 排错与 3D 球体实现

简介:面向需要构建全球数据可视化地图的前端开发工程师、数据分析师及大屏展示设计人员,这份压缩包提供了基于 ECharts 的完整世界地图 js 与 json 数据文件,可直接用于人口、GDP、疫情、贸易、航班航线等地理分布场景的快速展示与二次开发。…

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

hermes-agent:轻量级AI Agent信使架构解析与实践

项目标题只有"hermes-agent"这一个词,说实话一开始我也愣了一下。但干这行久了就明白,这种命名方式背后通常藏着一个很具体的痛点。Hermes在希腊神话里是 messengers——众神的信使,负责在神与人之间传递消息。放到技术语境里&…

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

身份证号同步指南:从踩坑到沉淀的完整方法论

接到一个把用户身份证号从老会员库同步到新用户中心的活儿,刚开始以为就是个普通的数据迁移,结果第一轮联调就把我干懵了:源库字段类型是 varchar(30),有的带空格,有的是全角数字,还有一批老数据是15位身份…

作者头像 李华