Datawhale AI 夏令营第五期 CV竞赛方向Task1笔记--初识yolo模型
本期(第五期)是Datawhale AI 夏令营的最后一期,本次的活动是伴随着“2024“大运河杯”数据开发应用创新大赛——城市治理”活动一起进行开展进行的。
一、赛题简介
1.赛题目标
开发一套智能识别系统,能够自动检测和分类城市管理中的违规行为。该系统应利用先进的图像处理和计算机视觉技术,通过对摄像头捕获的视频进行分析,自动准确识别违规行为,并及时向管理部门发出告警,以实现更高效的城市管理。
2.赛题类型
本赛题为计算机视觉中的目标检测问题。
计算机视觉方向有:
1、图像分类
2、目标检测
3、图像分割
4、目标跟踪
5、图像滤波与降噪
6、图像增强
7、三维重建
8、图像检索。
目标检测
1.目标检测概念
目标检测(Object Detection)是计算机视觉领域中的一项核心技术,它旨在让计算机能够像人眼一样识别和定位图像中的物体。具体来说,它不仅需要识别出图像中有哪些对象,还要确定它们在图像中的位置(通常以边界框的形式表示)以及它们的类别。
目标检测的本质是对视觉信息进行解析,使计算机能够理解图像中的内容。这涉及到图像处理、特征提取、模式识别和机器学习等多个层面。在技术层面,目标检测要解决的问题包括但不限于:对象分类、位置估计、尺寸变化、遮挡处理、背景干扰以及实时处理能力等。
2. 主流解决方式
目前,基于深度学习的方法是目标检测领域的主流解决方式,它通常分为两类:
- 两阶段检测方法:这种方法先从图像中提取出潜在的对象候选区域,然后对这些区域进行详细的分类和边界框精调。代表模型包括R-CNN系列(如Fast R-CNN, Faster R-CNN)和基于区域的全卷积网络(如Mask R-CNN)。
- 单阶段检测方法:这种方法直接在图像上预测对象的类别和位置,速度通常更快,但在准确度上可能略逊于两阶段方法。代表模型包括YOLO(You Only Look Once)、SSD(Single Shot MultiBox Detector)和RetinaNet等。
近年来,Transformer架构也被引入到目标检测中,如DETR(Detection Transformer)模型,这标志着目标检测技术的一个新的发展方向。参考:
1.目标检测简介
3.赛题分析
3.1 问题定义:
根据给定的城管视频监控数据集,进行城市违规行为的检测。违规行为主要包括垃圾桶满溢、机动车违停、非机动车违停等。
选手需要能够从视频中分析并标记出违规行为,提供违规行为发生的时间和位置信息。
【机动车违停】
机动车在设有禁止停车标志、标线的路段停车,或在非机动车道、人行横道、施工地段等禁止停车的地方停车。具体包含以下:
1、无论有无禁停标志,机动车道禁止车辆停放;
2、距路口、桥梁50米以内禁止车辆停放;
3、距公交车站、消防栓、消防队、医院30米以内禁止使用上述设施以外的车辆停放;
4、禁止车辆双排停放、靠左侧停放、横向停放、逆向停放;
5、人行道仅允许在已设置的停车泊位内停车,禁止在停车泊位外停车;
6、在设有禁停标志、标线的路段,人行横道、施工路段,不得停车。
【非机动车违停】
非机动车(如自行车、电动车等)未按照规定停放在指定的非机动车停车泊位或停车线内,而是在非机动车禁停区域或未划定的区域(消防通道、盲道、非机动车停车区线外、机动车停车区等)随意停放。
【垃圾满溢】
生活垃圾收集容器内垃圾超过三分之二以上即为满溢。垃圾桶无法封闭、脏污且周边有纸屑、污渍、塑料、生活垃圾及杂物堆放。
【占道经营】
经营者占用城市道路、桥梁、城市广场等公共场所进行盈利性买卖商品或服务的行为。
3.1 数据集介绍
数据集包括包括视频数据与对应的JSON文件。
json文件的内容是每帧检测到的违规行为,包括以下字段:
- frame_id:违规行为出现的帧编号
- event_id:违规行为ID
- category:违规行为类别
- bbox:检测到的违规行为矩形框的坐标,[xmin,ymin,xmax,ymax]形式
标注示例如下:
[
{
"frame_id": 20,
"event_id": 1,
"category": "机动车违停",
"bbox": [200, 300, 280, 400]
},
{
"frame_id": 20,
"event_id": 2,
"category": "机动车违停",
"bbox": [600, 500, 720, 560]
},
{
"frame_id": 30,
"event_id": 3,
"category": "垃圾桶满溢",
"bbox": [400, 500, 600, 660]
}
]
3.2 提交格式
提交名为result
的文件夹,文件夹中包含每个视频对应的json结果文件,文件名与视频名对应。选手需要将文件夹打包成result.zip
进行上传。
json文件中包含了检测到的违规行为列表,若未检测到违规行为,则列表为空。
每个违规行为包含的字段如下:
- frame_id:违规行为出现的帧编号
- event_id:违规行为ID
- category:违规行为类别
- bbox:检测到的违规行为矩形框的坐标,[xmin,ymin,xmax,ymax]形式
- confidence:置信度
提交的json示例如下:
[
{
"frame_id": 20,
"event_id": 1,
"category": "机动车违停",
"bbox": [200, 300, 280, 500],
"confidence": 0.85
},
{
"frame_id": 20,
"event_id": 2,
"category": "垃圾桶满溢",
"bbox": [600, 500,720, 560],
"confidence": 0.90
},
{
"frame_id": 30,
"event_id": 3,
"category": "垃圾桶满溢",
"bbox": [400, 500, 500, 560],
"confidence": 0.78
}
]
3.3 评估指标
使用F1score、MOTA指标来评估模型预测结果。
对每个json文件得到两个指标的加权求和,最终得分为所有文件得分取均值。
注1:若真实目标框与预测框IOU大于0.5,则判定目标正确识别。若MOTA指标为负,则该类别精度得分为0。
注2:若该视频中没有某个类别的目标,则此类别计算均值时,忽略该视频。
评估指标补充:
- 精确率(Precision):精确率也叫查准率,是在识别出的物体中,正确的正向预测 (True Positive,TP) 所占的比率。
- 召回率 (Recall):召回率 (Recall)是正确识别出的物体占总物体数的比率。
- 准确率(Accuracy):准确率是指模型正确预测的样本数量占总样本数量的比例。
- F1分数(F1 Score):F1分数是精确率和召回率的调和平均值,它综合考虑了模型的查准率和查全率。
PR曲线:Precision-Recall曲线- AP( Average Precision ):PR曲线下的面积,综合考量了 recall 和 precision 的影响,反映了模型对某个类别识别的好坏。
- mAP ( mean Average Precision ):, 即各类别AP的平均值,衡量的是在所有类别上的平均好坏程度。
- 交并比(Intersection over Union,IoU)是一种常用的评估目标检测和图像分割模型性能的指标。IoU用于衡量模型预测的边界框(或分割结果)与真实标注之间的重叠程度。
- 其中,交集表示模型预测的边界框与真实边界框的交集区域的面积,并集表示两个边界框的并集区域的面积。
- IoU的取值范围在0到1之间,值越接近1表示模型的预测结果与真实情况重合程度越高,性能也越好。通常情况下,当IoU大于一个设定的阈值(如0.5或0.75)时,我们会将模型的预测结果视为正确的检测或分割。
二、BaseLine分析
1.数据集可视化
1.1 JSON标签读取
使用Visual Studio Code 查看:
1.加载和查看标注文件
train_anno = json.load(open('训练集(有标注第一批)/标注/45.json', encoding='utf-8')) # 加载训练集中的标注文件
train_anno[0], len(train_anno) # 输出标注数据的第一个条目和总数
- 加载一个标注文件 45.json,读取JSON格式的数据。
- 输出标注数据的第一个条目和标注条目的总数量。
2.读取并查看标注文件
json_data = pd.read_json('训练集(有标注第一批)/标注/45.json')
print(jason_data)
结果如图:
1.2 视频文件查看
- 记载并读取视频帧
video_path = '训练集(有标注第一批)/视频/45.mp4'
cap = cv2.VideoCapture(video_path)
while True:
# 读取下一帧
ret, frame = cap.read()
if not ret:
break
break
print(frame.shape)
print(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)))
结果:
2. 绘制矩形框并保存
video_path = '训练集(有标注第一批)/视频/45.mp4'
cap = cv2.VideoCapture(video_path)
while True:
# 读取下一帧
ret, frame = cap.read()
if not ret:
break
break
print(frame.shape)
print(int(cap.get(cv2