YOLO11智慧城市应用:违章停车识别系统案例
YOLO11智慧城市应用:违章停车识别系统案例
1. 引言:当城市管理遇上AI视觉
你有没有发现,现在很多城市的街道管理越来越“聪明”了?以前处理违章停车,主要靠人工巡逻、贴罚单,效率低还容易有遗漏。现在,很多地方开始用摄像头自动识别违章停车,发现问题就自动上报,整个过程又快又准。
这背后,就是计算机视觉技术在发挥作用。今天要聊的YOLO11,就是做这件事的“高手”。它是一个专门用来做目标检测的深度学习模型,简单说,就是让计算机学会“看”图片和视频,然后找出里面有什么东西、在什么位置。
你可能听说过YOLO系列,从YOLOv1到现在的YOLO11,每一代都在速度、精度上有所提升。YOLO11作为最新版本,在智慧城市这种需要实时处理大量视频流的场景里,表现尤其出色。
这篇文章,我就带你看看怎么用YOLO11来搭建一个违章停车识别系统。我会从环境准备、数据准备、模型训练,到实际部署和效果展示,一步步讲清楚。就算你之前没怎么接触过深度学习,跟着做下来,也能跑通整个流程。
2. 环境准备:一键搞定开发环境
做深度学习项目,最头疼的往往不是写代码,而是配环境。不同的库版本不兼容、CUDA驱动问题、依赖包冲突……这些坑很多人都踩过。
好在现在有更简单的方法。CSDN星图镜像广场提供了一个基于YOLO11的完整开发环境镜像,里面已经把Python、PyTorch、Ultralytics库这些必要的工具都装好了,还预置了Jupyter Notebook和SSH服务。
2.1 两种使用方式,随你选择
这个镜像提供了两种使用方式,适合不同的工作习惯。
方式一:用Jupyter Notebook(适合初学者和快速实验)
如果你喜欢在网页里写代码、看结果,Jupyter Notebook是最方便的选择。启动镜像后,系统会提供一个访问链接,点开就能在浏览器里看到一个熟悉的Jupyter界面。
在这里,你可以新建Python笔记本,直接写代码、运行、看结果。所有的代码和输出都会保存在同一个文件里,特别适合做实验和演示。
方式二:用SSH连接(适合习惯命令行的高手)
如果你更习惯在终端里操作,或者需要运行一些后台任务,SSH连接会更适合。镜像启动后,会提供SSH的连接信息,包括IP地址、端口、用户名和密码。
用你喜欢的SSH工具(比如PuTTY、Termius,或者macOS/Linux自带的终端)连上去,就能得到一个完整的Linux命令行环境。在这里,你可以运行Python脚本、管理文件、安装额外的包,做任何你想做的事情。
两种方式其实访问的是同一个环境,文件系统是共享的。你可以在Jupyter里写代码,然后在SSH里运行长时间的训练任务,非常灵活。
2.2 快速验证环境
不管用哪种方式,进入环境后,第一件事就是验证YOLO11能不能正常工作。
打开终端或者Jupyter,运行下面这行简单的命令:
from ultralytics import YOLO
# 加载一个预训练模型
model = YOLO('yolo11n.pt') # 这是YOLO11的纳米版本,最小最快
# 用一张测试图片看看效果
results = model('https://ultralytics.com/images/bus.jpg')
# 显示结果
results[0].show()
如果一切正常,你会看到模型成功检测出了图片里的公交车、行人等目标,并且画上了框。这说明环境配置没问题,可以开始我们的项目了。
3. 数据准备:让模型认识“违章停车”
训练一个AI模型,就像教小孩认东西。你得先准备很多“教材”——也就是标注好的图片,告诉模型:“看,这种停在斑马线上的车,就是违章停车;这种停在正规车位里的车,就不是。”
3.1 数据从哪里来?
对于违章停车识别,我们需要两种数据:
- 道路场景图片:包含各种道路环境的图片,最好是监控摄像头拍的那种俯视角度。
- 车辆标注信息:每张图片里,每辆车的位置(用框标出来),以及它是不是违章停车。
这些数据可以从几个渠道获取:
- 公开数据集:像UA-DETRAC、Cityscapes这些数据集里,有带标注的车辆图片。
- 模拟生成:用游戏引擎(比如GTA V)生成虚拟的道路和车辆场景,可以批量制造标注数据。
- 实际采集:如果有条件,可以从交通管理部门获取脱敏后的真实监控数据。
我建议刚开始用公开数据集,等模型效果不错了,再用自己的数据做微调。
3.2 数据标注格式
YOLO11用的标注格式很简单,每张图片对应一个.txt文件。比如有一张图片叫road_001.jpg,它的标注文件就是road_001.txt。
标注文件里,每一行代表一个物体,格式是这样的:
<class_id> <x_center> <y_center> <width> <height>
举个例子:
0 0.45 0.32 0.12 0.08
1 0.67 0.54 0.09 0.11
这里的数字都是相对坐标(0到1之间):
0和1是类别编号(比如0代表“正常停车”,1代表“违章停车”)0.45 0.32是框的中心点坐标0.12 0.08是框的宽度和高度
3.3 准备数据集的目录结构
把图片和标注文件整理成这样的结构:
datasets/
└── parking_violation/
├── train/
│ ├── images/ # 训练图片
│ └── labels/ # 训练标注
├── val/
│ ├── images/ # 验证图片
│ └── labels/ # 验证标注
└── data.yaml # 数据集配置文件
data.yaml文件告诉YOLO11你的数据集信息:
# data.yaml
path: /path/to/datasets/parking_violation # 数据集路径
train: train/images # 训练集图片路径
val: val/images # 验证集图片路径
# 类别信息
names:
0: normal_parking
1: violation_parking
4. 模型训练:教AI识别违章停车
数据准备好了,现在可以开始训练模型了。训练的过程,就是让模型一遍遍看这些标注好的图片,不断调整内部的参数,直到能准确识别出违章停车。
4.1 进入项目目录
首先,我们需要进入YOLO11的项目目录。从镜像提供的环境来看,项目应该在ultralytics-8.3.9/这个目录下:
cd ultralytics-8.3.9/
这个目录里包含了YOLO11的所有源代码、示例脚本和工具。
4.2 开始训练
训练模型只需要一行命令:
python train.py
不过,我们通常需要指定一些参数,让训练更适合我们的任务。一个完整的训练命令可能是这样的:
python train.py \
--data datasets/parking_violation/data.yaml \ # 数据集配置
--model yolo11n.pt \ # 使用YOLO11纳米版作为基础
--epochs 100 \ # 训练100轮
--imgsz 640 \ # 输入图片尺寸640x640
--batch 16 \ # 每批处理16张图片
--workers 4 \ # 用4个进程加载数据
--name parking_violation_v1 # 给这次训练起个名字
这些参数是什么意思?
--epochs 100:让模型把整个训练集看100遍。一般来说,数据越多、任务越复杂,需要的训练轮数就越多。--imgsz 640:把图片缩放到640x640大小再输入模型。尺寸越大,模型看得越清楚,但训练速度越慢。--batch 16:一次处理16张图片。批大小影响训练速度和内存使用,需要根据你的显卡来调整。--workers 4:用4个进程并行加载数据,这样不会让GPU等着数据。
4.3 训练过程监控
训练开始后,你会在终端看到类似这样的输出:
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
1/100 2.1G 1.234 0.876 0.543 32 640
2/100 2.1G 1.123 0.765 0.498 32 640
3/100 2.1G 1.045 0.712 0.467 32 640
...
这里有几个关键指标:
box_loss:框的位置预测得准不准,数值越小越好cls_loss:分类预测得准不准,数值越小越好GPU_mem:显存使用量,确保不超过显卡容量
训练过程中,YOLO11会自动保存效果最好的模型。通常保存在runs/detect/parking_violation_v1/weights/目录下,其中best.pt就是效果最好的模型。
4.4 训练结果分析
训练完成后,你会看到类似这样的结果展示:
这张图里包含了丰富的信息:
- 左上角:损失函数的变化曲线,可以看到随着训练进行,损失值在下降
- 右上角:模型在验证集上的表现指标
- 下面几张小图:模型在测试图片上的检测效果
重点看这几个指标:
- mAP50:这是目标检测最常用的评价指标,数值在0到1之间,越接近1说明模型越好。0.7以上就算不错,0.8以上就很好用了。
- Precision(精确率):模型说“这是违章停车”的时候,有多大概率是对的。
- Recall(召回率):真正的违章停车里,有多少被模型找出来了。
一般来说,我们希望精确率和召回率都高,但实际中往往需要权衡。对于违章停车识别,我们可能更看重精确率——宁可漏掉一些,也不要误判很多,否则会引起不必要的纠纷。
5. 模型部署:从实验到实际应用
模型训练好了,测试效果也不错,接下来就要把它用起来。在实际的智慧城市系统中,模型部署有几个关键考虑。
5.1 模型优化:让推理更快
训练好的模型文件(.pt格式)包含了所有参数,但可能不是最优的部署格式。我们可以做一些优化:
from ultralytics import YOLO
# 加载训练好的模型
model = YOLO('runs/detect/parking_violation_v1/weights/best.pt')
# 导出为ONNX格式(很多推理框架都支持)
model.export(format='onnx')
# 或者导出为TensorRT格式(如果用在NVIDIA设备上)
model.export(format='engine', device=0) # device=0表示用第一块GPU
ONNX是一种通用的模型格式,可以在各种平台上运行。TensorRT是NVIDIA的推理加速引擎,能让模型在GPU上跑得更快。
5.2 编写推理脚本
实际部署时,我们需要一个脚本来处理视频流。下面是一个简单的示例:
import cv2
from ultralytics import YOLO
import time
class ParkingViolationDetector:
def __init__(self, model_path='best.pt'):
# 加载模型
self.model = YOLO(model_path)
# 定义违章停车的类别ID(根据你的数据标注来定)
self.violation_class_id = 1
# 设置检测参数
self.conf_threshold = 0.5 # 置信度阈值,大于0.5才认为是检测到了
self.iou_threshold = 0.45 # 重叠阈值,用于去掉重复的框
def process_frame(self, frame):
"""处理一帧图像"""
start_time = time.time()
# 用模型检测
results = self.model(
frame,
conf=self.conf_threshold,
iou=self.iou_threshold,
verbose=False # 不输出详细信息
)
violation_count = 0
violation_boxes = []
# 分析检测结果
for result in results:
boxes = result.boxes
if boxes is not None:
for box in boxes:
# 获取框的位置、置信度和类别
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
confidence = box.conf[0].cpu().numpy()
class_id = int(box.cls[0].cpu().numpy())
# 如果是违章停车
if class_id == self.violation_class_id:
violation_count += 1
violation_boxes.append((x1, y1, x2, y2, confidence))
# 在图上画框(红色表示违章)
cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 0, 255), 2)
label = f"Violation: {confidence:.2f}"
cv2.putText(frame, label, (int(x1), int(y1)-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
# 计算处理时间
process_time = time.time() - start_time
fps = 1.0 / process_time if process_time > 0 else 0
# 在图上显示统计信息
info_text = f"Violations: {violation_count} | FPS: {fps:.1f}"
cv2.putText(frame, info_text, (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
return frame, violation_count, violation_boxes
def process_video(self, video_path, output_path=None):
"""处理整个视频文件"""
cap = cv2.VideoCapture(video_path)
if output_path:
# 获取视频参数,用于保存结果
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
total_violations = 0
frame_count = 0
while True:
ret, frame = cap.read()
if not ret:
break
# 处理每一帧
processed_frame, violations, _ = self.process_frame(frame)
total_violations += violations
frame_count += 1
if output_path:
out.write(processed_frame)
# 显示实时结果(按q退出)
cv2.imshow('Parking Violation Detection', processed_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
if output_path:
out.release()
cv2.destroyAllWindows()
print(f"处理完成!总共处理{frame_count}帧,发现{total_violations}次违章停车")
return total_violations
# 使用示例
if __name__ == "__main__":
detector = ParkingViolationDetector('best.pt')
# 处理视频文件
detector.process_video('test_video.mp4', 'output_video.mp4')
# 或者处理摄像头实时流
# detector.process_video(0) # 0表示默认摄像头
这个脚本做了几件事:
- 加载训练好的模型
- 处理每一帧图像,检测违章停车
- 在图像上标记出违章车辆
- 显示实时统计信息(违章数量、处理速度)
- 可以处理视频文件,也可以处理摄像头实时流
5.3 系统集成:让识别结果发挥作用
在实际的智慧城市系统中,光检测出来还不够,还需要把结果用起来。一个完整的违章停车识别系统可能包括:
- 视频接入模块:从各个路口的摄像头获取视频流
- AI分析模块:用我们训练好的模型分析视频,识别违章停车
- 告警生成模块:发现违章后,生成告警信息(时间、地点、车牌号等)
- 数据存储模块:把告警信息保存到数据库
- 业务对接模块:把告警推送给执法系统或停车管理系统
这里有一个简单的告警生成示例:
import json
from datetime import datetime
class ViolationAlert:
def __init__(self, camera_id, location):
self.camera_id = camera_id
self.location = location
self.violations = []
def add_violation(self, frame_id, timestamp, box_coords, confidence, vehicle_info=None):
"""添加一条违章记录"""
violation = {
'id': len(self.violations) + 1,
'frame_id': frame_id,
'timestamp': timestamp,
'location': self.location,
'camera_id': self.camera_id,
'box_coords': box_coords, # [x1, y1, x2, y2]
'confidence': float(confidence),
'vehicle_info': vehicle_info or {},
'status': 'new', # new, processed, closed
'created_at': datetime.now().isoformat()
}
self.violations.append(violation)
return violation
def generate_report(self, start_time, end_time):
"""生成时间段内的违章报告"""
report = {
'camera_id': self.camera_id,
'location': self.location,
'period': {
'start': start_time.isoformat(),
'end': end_time.isoformat()
},
'total_violations': len(self.violations),
'violations': self.violations,
'generated_at': datetime.now().isoformat()
}
return report
def save_to_database(self, db_connection):
"""保存到数据库"""
# 这里简化处理,实际需要根据数据库类型来写
for violation in self.violations:
if violation['status'] == 'new':
# 插入数据库逻辑
print(f"保存违章记录: {violation}")
violation['status'] = 'processed'
def send_to_management_system(self, api_endpoint):
"""推送到管理系统"""
import requests
report = self.generate_report(
datetime.now().replace(hour=0, minute=0, second=0),
datetime.now()
)
try:
response = requests.post(
api_endpoint,
json=report,
headers={'Content-Type': 'application/json'}
)
if response.status_code == 200:
print("违章数据已成功推送到管理系统")
return True
else:
print(f"推送失败: {response.status_code}")
return False
except Exception as e:
print(f"推送出错: {e}")
return False
# 使用示例
if __name__ == "__main__":
# 创建一个告警实例
alert_system = ViolationAlert(
camera_id="CAM-001",
location="中山路-人民路交叉口"
)
# 模拟检测到违章
alert_system.add_violation(
frame_id=1001,
timestamp=datetime.now().isoformat(),
box_coords=[320, 240, 400, 300], # 框的位置
confidence=0.85,
vehicle_info={'color': 'white', 'type': 'sedan'}
)
# 生成报告
report = alert_system.generate_report(
start_time=datetime.now().replace(hour=8, minute=0, second=0),
end_time=datetime.now().replace(hour=9, minute=0, second=0)
)
print(f"8点到9点共发现{report['total_violations']}次违章")
# 保存到数据库(需要实际数据库连接)
# alert_system.save_to_database(db_connection)
# 推送到管理系统(需要实际API地址)
# alert_system.send_to_management_system("http://api.example.com/violations")
6. 效果优化与实际问题解决
在实际部署中,你可能会遇到各种问题。这里分享一些常见的挑战和解决方法。
6.1 提高检测准确率
如果模型在某些场景下表现不好,可以试试这些方法:
1. 数据增强 训练时加入更多样的数据变化,让模型适应各种情况:
# 在训练时加入数据增强
python train.py \
--data datasets/parking_violation/data.yaml \
--model yolo11n.pt \
--epochs 150 \
--imgsz 640 \
--batch 16 \
--augment True \ # 开启数据增强
--hsv_h 0.015 \ # 随机调整色调
--hsv_s 0.7 \ # 随机调整饱和度
--hsv_v 0.4 \ # 随机调整亮度
--degrees 10.0 \ # 随机旋转角度
--translate 0.1 \ # 随机平移
--scale 0.5 \ # 随机缩放
--shear 0.0 \ # 随机剪切
--perspective 0.0 \ # 透视变换
--flipud 0.0 \ # 上下翻转概率
--fliplr 0.5 \ # 左右翻转概率
--mosaic 1.0 \ # Mosaic数据增强概率
--mixup 0.0 \ # Mixup数据增强概率
--copy_paste 0.0 # 复制粘贴增强概率
2. 调整模型大小 YOLO11有不同大小的版本,可以根据需要选择:
yolo11n.pt:纳米版,最小最快,适合边缘设备yolo11s.pt:小版,平衡速度和精度yolo11m.pt:中版,精度更高yolo11l.pt:大版,精度最高yolo11x.pt:超大版,精度极致但速度慢
如果纳米版精度不够,可以试试小版或中版。
3. 后处理优化 调整检测后的处理参数:
# 调整置信度阈值和NMS参数
results = model(
frame,
conf=0.25, # 降低置信度阈值,检测更多目标(但可能有更多误检)
iou=0.45, # NMS的IOU阈值,值越小越容易去掉重叠框
max_det=100, # 每张图最多检测100个目标
agnostic_nms=False, # 是否使用类别无关的NMS
classes=[1] # 只检测违章停车类别(如果知道类别ID)
)
6.2 提升处理速度
在实际的监控系统中,处理速度很重要。一些优化建议:
1. 降低输入分辨率
# 使用更小的输入尺寸
results = model(frame, imgsz=320) # 从640降到320,速度能提升3-4倍
2. 使用TensorRT加速 如果用的是NVIDIA GPU,可以转成TensorRT格式:
# 导出为TensorRT格式
model.export(format='engine', imgsz=640, batch=1, device=0)
# 加载TensorRT模型
trt_model = YOLO('best.engine')
3. 跳帧处理 对于实时性要求不高的场景,可以跳帧处理:
frame_skip = 2 # 每3帧处理1帧
frame_count = 0
while True:
ret, frame = cap.read()
if not ret:
break
frame_count += 1
# 只处理特定帧
if frame_count % (frame_skip + 1) == 0:
results = model(frame)
# 处理结果...
else:
# 使用上一帧的结果,或者跳过
pass
6.3 处理特殊场景
夜间或低光照条件 监控摄像头在夜间画面质量会下降,可以:
- 训练时加入夜间数据:收集夜间违章停车图片加入训练集
- 图像增强:处理前先做图像增强
import cv2
import numpy as np
def enhance_low_light(image):
"""增强低光照图像"""
# 转换为LAB颜色空间
lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
# 分离通道
l, a, b = cv2.split(lab)
# 对L通道做CLAHE增强
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
cl = clahe.apply(l)
# 合并通道并转回BGR
limg = cv2.merge((cl, a, b))
enhanced = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
return enhanced
# 使用增强后的图像
enhanced_frame = enhance_low_light(frame)
results = model(enhanced_frame)
遮挡情况 车辆被部分遮挡时,检测可能不准。可以:
- 训练时加入更多遮挡样本
- 使用跟踪算法,结合多帧信息判断
from collections import defaultdict
import numpy as np
class VehicleTracker:
def __init__(self, max_age=30):
self.tracks = defaultdict(dict)
self.next_id = 1
self.max_age = max_age # 轨迹最大保留帧数
def update(self, detections, frame_id):
"""更新跟踪器"""
# detections: [(x1, y1, x2, y2, confidence, class_id), ...]
updated_tracks = {}
for det in detections:
x1, y1, x2, y2, conf, cls = det
center_x = (x1 + x2) / 2
center_y = (y1 + y2) / 2
# 简单的最近邻匹配
matched_id = None
min_dist = float('inf')
for track_id, track in self.tracks.items():
if frame_id - track['last_seen'] > self.max_age:
continue
# 计算距离
last_center = track['last_center']
dist = np.sqrt((center_x - last_center[0])**2 +
(center_y - last_center[1])**2)
if dist < 50 and dist < min_dist: # 50像素内的阈值
min_dist = dist
matched_id = track_id
if matched_id is not None:
# 更新现有轨迹
track = self.tracks[matched_id]
track['last_center'] = (center_x, center_y)
track['last_seen'] = frame_id
track['history'].append((center_x, center_y, frame_id))
updated_tracks[matched_id] = track
else:
# 创建新轨迹
new_track = {
'id': self.next_id,
'first_seen': frame_id,
'last_seen': frame_id,
'last_center': (center_x, center_y),
'history': [(center_x, center_y, frame_id)],
'class_id': cls
}
updated_tracks[self.next_id] = new_track
self.next_id += 1
self.tracks = updated_tracks
return self.tracks
# 使用跟踪器
tracker = VehicleTracker()
frame_id = 0
while True:
ret, frame = cap.read()
if not ret:
break
# 检测
results = model(frame)
detections = []
for box in results[0].boxes:
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
conf = box.conf[0].cpu().numpy()
cls = int(box.cls[0].cpu().numpy())
detections.append((x1, y1, x2, y2, conf, cls))
# 更新跟踪
tracks = tracker.update(detections, frame_id)
# 分析轨迹,判断是否违章停车
for track_id, track in tracks.items():
if len(track['history']) > 10: # 至少跟踪了10帧
# 计算车辆是否静止
positions = np.array([pos[:2] for pos in track['history'][-10:]])
movement = np.std(positions, axis=0).sum() # 位置变化的标准差
if movement < 5.0: # 位置变化很小,可能是静止的
# 检查是否在禁停区域(需要结合地图信息)
# 如果是,标记为违章停车
pass
frame_id += 1
7. 总结
通过这篇文章,我们完整地走了一遍用YOLO11构建违章停车识别系统的流程。从环境准备、数据标注、模型训练,到实际部署和效果优化,每个环节都有具体的代码示例和实践建议。
这个系统的价值很明显:它能让城市停车管理更高效、更公平。以前靠人工巡逻,难免有疏漏,现在用AI 24小时监控,违章行为无处遁形。而且系统可以自动记录、自动上报,大大减少了人力成本。
不过也要注意,技术只是工具,怎么用好它更重要。在实际部署时,要考虑隐私保护的问题,比如对车牌号做模糊处理;要考虑误判的情况,设置合理的复核机制;还要考虑不同天气、不同光照条件下的稳定性。
YOLO11作为目前最先进的目标检测模型之一,在智慧城市领域还有很多应用场景等着我们去探索。比如交通流量统计、行人闯红灯检测、垃圾堆放识别等等。掌握了这个工具,你就能为智慧城市建设贡献更多有价值的解决方案。
技术总是在进步,YOLO系列也在不断更新。但核心的思路和方法是相通的:理解问题、准备数据、训练模型、部署应用、持续优化。希望这篇文章能帮你迈出第一步,在实际项目中用起来,解决真实世界的问题。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)