5266张占道经营检测数据集:VOC与YOLO双格式实战指南
2026/9/8 21:57:12 网站建设 项目流程

简介:面向智慧城市城管场景,占道经营与户外摆摊目标检测数据集覆盖5000余张典型样本,可用于城市违规经营识别、街道治理监测等视觉任务,适合计算机视觉初学者及智慧城市项目开发者训练目标检测模型。数据集共1个类别(zdjy),标注框总数5799个,包含户外摊点、路边占道等常见状态;同时提供Pascal VOC与YOLO两种格式,可直接接入YOLO系列、Faster R-CNN等常见目标检测框架。资源包共2000个文件,以XML标注文件为主,另含1个说明txt,压缩包整体约631.79MB,便于快速下载解压;文件名以firc_zdjy统一命名,由labelImg标注工具生成,矩形框标注规范、类别边界清晰。数据集声明仅保证标注准确合理,不附带训练权重或精度承诺,适合作为算法验证与模型调优的纯净数据源。当前已有1335人学习下载,适合有基础的目标检测实践者按需取用。

1. 智慧城市里“摆摊”这个目标,为什么值得单独做一个数据集

先讲一个我在实际项目里反复遇到的现象:智慧城市项目做了好几年,算法列表里有人脸识别、车辆识别、火焰检测、垃圾满溢检测,但真正让城管部门觉得“这玩意儿有点用”的,往往不是那些炫技的模型,而是“占道经营识别”这类看起来特别朴素的功能。

原因不复杂。城市管理里最高频、最让一线执法队员头疼的案件,就是流动摊贩和店外经营。以前靠人工巡查,一个人管一条街,一天走两遍,摊贩跟你打游击,你来了他走,你走了他来。现在要求“非现场执法”“被动巡查变主动发现”,视频监控覆盖越来越密,AI自动发现占道摆摊就成了刚需。但这个刚需背后有个尴尬的现状:市面上的开源数据集大多聚焦行人、车辆、交通标志这些通用目标,专门为城市管理场景标注的摆摊数据集凤毛麟角。你拿COCO预训练权重直接去识别“摊贩”,效果惨不忍睹——因为摆摊这个目标,无论是视觉形态还是场景分布,都跟通用目标差异巨大。

所以这个数据集的价值一句话就能概括:把“占道经营/户外摆摊”从通用目标检测里单独拎出来,做成一个专门的1类别检测数据集,5266张图,VOC和YOLO双格式,拿来就能训练、能评估、能上线。

对于谁有用,我认为主要是三类人:

  • 智慧城市算法工程师,正在做或准备做城管类视觉算法,缺一份现成的、标注质量有保证的训练数据;
  • 算法产品经理或项目售前,需要用真实数据跑通Demo、估算算法效果的,这个数据集的规模刚好够做可行性验证;
  • 高校做目标检测方向研究的学生,想找一个非COCO、非VOC的垂直场景数据集做小样本、领域迁移之类的实验。

我自己拿到一份数据集的第一步,不是直接扔进训练脚本,而是先做整体盘点和清洗。这个习惯帮我避过不少坑。下面我把这套流程完整拆开讲。

2. 5266张1类别的数据集,从原始素材到VOC+YOLO双格式

2.1 数据从哪来,初筛怎么做

占道经营的数据获取渠道,跟一般数据集不太一样。我在实际项目中接触到的来源主要是三类:一是城市管理部门的监控视频抽帧,这是最理想的,角度高、场景真实、覆盖广;二是执法记录仪和巡查人员手机拍摄的现场照片,角度偏平视,光线和距离变化大;三是网格员上报案件时附带的现场图片,这部分噪声最大,但场景多样性最好。

初筛这一步很多人会忽略,但恰恰是决定数据集质量的关键环节。我自己会做三层过滤:

第一层去重。视频抽帧出来的图片,相邻帧之间相似度极高,直接全量放进数据集会造成训练集和验证集“近亲繁殖”,评估指标虚高。我一般按场景和内容做感知哈希去重,或者在抽帧时直接隔N帧抽一张,而不是连续抽。

第二层去模糊。摊贩是动态目标,手机拍的图也经常糊。模糊图放进数据集,相当于强行让模型去学“模糊的特征”,对收敛没有任何帮助。用Laplacian方差做一下清晰度筛选,低于阈值的直接丢。

第三层去空帧。监控画面里大量时间段是没人的,这类图不丢的话,会把“背景”学进“无目标”的先验里,导致模型在空场景下误检率偏高。我筛完空旷画面后,还会再人工快速过一遍,确保每张图里至少有一个可标注的有效目标。

三层筛完,5266张这个数字就比较“干净”了。别小看这个规模,对单类别检测任务来说,5000多张已经足够训练出一个能进测试环境做POC的模型,前提是标注质量跟得上。

2.2 标注规范:框的是什么,边界在哪

标注规范这件事,直接决定模型学出来的“摆摊”到底是个什么东西。我跟标注团队对规范时,反复强调一个原则:框住“经营行为”的完整空间,而不是只框“人”或者只框“货”。

具体标法是这样的:

  • 如果是一个推车摊贩,框要覆盖推车、货物、经营者以及摊前正在选购的顾客,因为顾客的存在也是“这里有经营活动”的重要视觉线索;
  • 如果是地面摆摊(比如水果摊、菜摊),框要覆盖摊开的货物区域,可以适当含一点周边地面,给模型学习留出上下文;
  • 如果是店外经营(桌椅摆到人行道上),框要覆盖超出店门的经营范围,通常从门口台阶到外摆边界。

类名方面,我用过stall,也见过别人用vendorstreet_vendor,都行,只要训练和推理阶段保持一致。数据集里只有一个类别,这也是刻意的设计——先回答“有没有摆摊”这个问题,至于“是水果摊还是烧烤摊”,是第二步才需要考虑的事,加类别会显著增加标注成本,而且对执法流程来说,先发现案件再人工看画面,比让算法细分要可靠得多。

边界情况也要提前定义:骑电动车等红灯的摊贩算不算?我的判断是,如果车上有明显货物且停在非机动车道或路口,算;只是普通行人路过,不算。帐篷底下的摊位怎么框?按帐篷的外轮廓框,因为这是视觉上最稳定的区域。这些规则不确定清楚,标注员每人一套标准,出来的数据集就没法用了。

2.3 VOC和YOLO两套格式是怎么落地的

标注工具我用的是labelImg和X-AnyLabeling的组合。labelImg老牌稳定,适合大批量标注;X-AnyLabeling自带SAM辅助标注能力,对边界稍微复杂的摊位能省不少时间。标注完成后默认导出的就是Pascal VOC格式的XML文件。

VOC格式是目标检测领域的“通用语”,结构上就是annotation根节点下面挂folderfilenamesize和若干个object节点。比如:

<annotation> <folder>JPEGImages</folder> <filename>img_0001.jpg</filename> <size> <width>1920</width> <height>1080</height> <depth>3</depth> </size> <object> <name>stall</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>612</xmin> <ymin>380</ymin> <xmax>1180</xmax> <ymax>760</ymax> </bndbox> </object> </annotation>

YOLO格式则完全不是一回事,它用归一化的中心点坐标和宽高来表示目标,每行一个目标,格式就是类别id 中心x 中心y 宽 高。同样一个框,在YOLO的txt里长这样:

0 0.4667 0.5278 0.2958 0.3519

四个数值全部在0到1之间,跟图像宽高做了归一化。为什么要归一化?因为YOLO系列网络在训练时会做resize,坐标归一化以后,网络不用关系输入分辨率具体是多少,这能显著提升泛化能力。

提示:VOC里的xminyminxmaxymax是像素坐标,YOLO需要的是归一化的中心坐标和宽高。转换时要注意中心坐标用的是 (xmin+xmax)/2,不是 (xmax-xmin)/2,这两者差了十万八千里。我见过有人在这里写错公式,训练Loss一直不收敛,排查了半天才发现坐标算错了。

3. 格式转换里的隐藏坑:坐标换算只是最低要求

3.1 坐标系换算的核心公式

VOC转YOLO的公式其实很机械:

x_center = (xmin + xmax) / 2 / width y_center = (ymin + ymax) / 2 / height box_width = (xmax - xmin) / width box_height = (ymax - ymin) / height

把四个像素值都换算到0到1区间。写脚本时需要注意三个问题:

第一个问题是图片尺寸。XML里虽然存了sizewidthheight,但有些数据集图片被resize过,XML里的尺寸信息和实际图片对不上。所以读XML时要以XML标注为基准做校验,用PILcv2去实际读一遍图片大小,对比XML里的尺寸,不一致就说明数据被动过,这种图直接剔除。这类隐蔽问题在网上下载的数据集里很常见。

第二个问题是类别ID的映射。YOLO格式里类别用数字ID,这个ID的排序必须在训练时保持一致。如果你classes.txt里写的是stall排第一,转换脚本里该类别的ID就得是0。多类别数据集尤其容易在这里翻车——换机器、换环境后classes.txt顺序一变,所有标注就全乱了。这个数据集只有1个类别,自然ID永远是0,反而少了很多麻烦。

第三个问题是归一化精度。YOLO格式对精度要求不高,小数点后4到6位足够了。不要为了追求精确输出十几位小数,那只会让文件膨胀,对训练毫无帮助。

3.2 转换脚本的骨架参考

我自己的转换脚本一般长这样,结构清晰、可以复用:

import os import xml.etree.ElementTree as ET from PIL import Image def voc_to_yolo(xml_path, img_dir, output_dir, classes): tree = ET.parse(xml_path) root = tree.getroot() # 读取实际图片尺寸 filename = root.find('filename').text img_path = os.path.join(img_dir, filename) with Image.open(img_path) as img: width, height = img.size yolo_lines = [] for obj in root.iter('object'): name = obj.find('name').text if name not in classes: continue # 跳过未定义类别 class_id = classes.index(name) bbox = obj.find('bndbox') xmin = float(bbox.find('xmin').text) ymin = float(bbox.find('ymin').text) xmax = float(bbox.find('xmax').text) ymax = float(bbox.find('ymax').text) # 边界裁剪,防止越界 xmin = max(0, min(xmin, width - 1)) xmax = max(0, min(xmax, width - 1)) ymin = max(0, min(ymin, height - 1)) ymax = max(0, min(ymax, height - 1)) if xmin >= xmax or ymin >= ymax: continue # 剔除无效框 x_center = (xmin + xmax) / 2 / width y_center = (ymin + ymax) / 2 / height box_w = (xmax - xmin) / width box_h = (ymax - ymin) / height yolo_lines.append(f"{class_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}") if not yolo_lines: return False txt_name = os.path.splitext(filename)[0] + '.txt' with open(os.path.join(output_dir, txt_name), 'w') as f: f.write('\n'.join(yolo_lines)) return True

3.3 转换后必须做的核验

转换完不要急着开训练,先做一次可视化校验。我习惯把YOLO的txt标注反画回图片,也就是把归一化坐标再转成像素坐标,画框叠在原图上,随机抽三五十张肉眼确认。

怎么反画?就是上面公式的逆运算:

xmin = int((x_center - box_w / 2) * width) ymin = int((y_center - box_h / 2) * height) xmax = int((x_center + box_w / 2) * width) ymax = int((y_center + box_h / 2) * height)

画完检查几个点:框是否紧贴目标、有没有整体偏移、有没有被裁掉一半、大目标是不是被拆成了几个小框。数据集里的很多问题,只有可视化之后才暴露得出来。我在一次项目中就发现某些XML里的坐标小数点被截断过,框整体偏了10多个像素,不画出来根本注意不到。

提示:实际标注过程中,会有少量图片的XML文件损坏或内容缺失。建议转换脚本里加上try...except和日志输出,跑完统计一下成功转换的图片数和失败数,做到心里有数,而不是黑盒跑完直接拿去训练。

4. 5266张数据到底够不够用,训练时踩过的真实坑

4.1 先搞清楚评价口径,再谈效果好坏

很多人拿到数据集第一件事就是开训练,但我建议先花十分钟明确评价标准。目标检测领域有两个常用指标:mAP50mAP50-95

  • mAP50指的是IoU阈值设为0.5时的平均精度,日常POC汇报、给客户演示常用这个,数值一般比较好看;
  • mAP50-95是在0.5到0.95区间内按步长计算IoU阈值下的mAP再取平均,对框的精准度要求苛刻得多,数值会明显偏低。

以5266张单类别数据训练YOLOv8s(640分辨率,100个epoch左右)的经验来说,mAP50能做到0.85以上甚至接近0.9,但mAP50-95能在0.55到0.65之间就已经算很健康了。如果只报mAP50不讲另一个,客户觉得“哇好高”,但你心里必须清楚边界。我实测下来,这个数据规模做单类检测是“够用但不算富裕”的状态——能支撑POC和早期试点,但要上生产环境追求百路视频的稳定表现,还需要在训练策略和后续数据补充上下功夫。

4.2 摆摊目标真正的难点:小目标、遮挡、夜间

我在实际训练这个场景时,失分点主要集中在三类难例:

第一类是小目标。城管监控通常是高空机位,一个摊位在1080p画面里可能只有30×40像素,摊位的视觉纹理几乎看不清。YOLO系列在小目标上本来就偏弱,640输入下小目标信息进一步压缩。我的处理方案是:训练时设置imgsz=960甚至1280,推理时也保持同样分辨率。代价是推理速度变慢,但换取的是小目标召回率明显提升。另外,数据增强里开mosaiccopy-paste让模型多看一些“目标嵌入不同背景”的组合,也能缓解小目标样本不足的问题。

第二类是遮挡。树叶挡掉一半、遮阳棚挡住主体、人流把摊位挤得只剩一个角。这种样本在真实监控里占比非常高。解决思路有两条:一是在标注阶段就把“部分可见”的摊位正常标出来,让模型学会从局部特征推断整体;二是训练时开启hsv_hhsv_shsv_v这类颜色增强,模拟不同光照条件下目标的外观变化。

第三类是夜间和恶劣天气。这个数据集的图片如果白天多夜间少,夜间检测效果就会明显掉。常用的补救措施有:把图片转成灰度再做训练样本,模拟红外单色画面;或者用图像增强工具把白天图压暗、加噪、加模糊,扩充夜间域。但这些都只是缓解,根治还得靠补充真实的夜间样本。

4.3 训练配置的一个实操参考

如果让我给一份可复现的训练配置,大致是这样的:

  • 模型:YOLOv8s,兼顾速度和精度,POC阶段没必要直接上YOLOv8x;
  • 输入尺寸:960(或者你用640先跑通流程,再上960拉精度);
  • epochs:100起步,观察验证集Loss是否还在下降,如果还在降就加50;
  • batch size:根据显存来,24G显存可以开16,8G显存建议8左右,配合梯度累积;
  • 数据增强:默认增强全开,mosaic=1.0mixup=0.2copy_paste=0.3
  • 优化器:AdamW或SGD都行,我个人习惯SGD配cosine lr,收敛稳。

训练过程中还有一个小建议——不要只盯最后的checkpoint。用YOLO训练时,验证集mAP最高的epoch不一定在训练末尾,早停或保留best.pt非常重要,否则你可能拿着一个过拟合的模型去做推理部署,然后又回头怀疑是数据集的问题。

5. 从数据集到线上执法,部署阶段被忽略的几个问题

5.1 训练域和部署域不一致,是最常见的精度杀手

数据集做得再好,训练和部署的“域差异”如果不管,上线一样翻车。什么叫域差异?训练集里的画面是平视手机拍的,部署时全是俯视监控画面,模型泛化能力再强也会掉点。

我建议拿到数据后先大致看一遍图片的拍摄视角、画面比例、目标尺度分布,再对比你自己的摄像头视角。如果差异大,优先做的事情是准备一小批目标场景的真实截图,做几次“增量微调”,而不是直接拿原数据集训完就上。

5.2 推理链路和去抖逻辑

检测模型跑在视频流上,不等于每帧都要检测。我的做法是抽帧检测——比如每3到5帧取1帧送模型,降低算力消耗,同时在业务逻辑上做“连续确认”。

连续确认的意思是,同一路视频流里,连续N次检测(比如连续3次)都发现目标,才触发告警。这样能过滤掉大量的瞬时误检,比如路人跟摊贩擦肩而过、车辆短暂停留这类情况。反过来,如果目标在画面中消失了,也连续确认2次再恢复,避免目标闪烁导致的重复报警。

告警附带截图和前后几秒的录像片段,这一点我认为比模型本身更影响使用体验。城管执法讲究取证,光有“检测到摆摊”的文字提示没有意义,必须有一张清晰的截图和一段完整的视频作为执法依据。

5.3 置信度阈值要按业务调,别用默认值

很多人部署时直接用模型的默认置信度阈值,比如0.25,这在有客户盯着看效果的项目里通常会显得误报很多。我的经验是:先跑一段真实录像,统计误报和漏报的比例,再决定调高还是调低阈值。

如果目标是“减少执法队员无效出勤”,阈值往高了调(比如0.5到0.6),宁可漏报让系统提示“待人工复核”,也不要满天飞告警把人搞烦。如果目标是“确保没有一起违规被漏掉”,阈值放低(0.2左右),依靠人工复核来弥补精度。这两个方向没有绝对的对错,取决于客户更怕“漏”还是更怕“吵”。

我个人的体会是,占道经营算法项目,80%的精力其实花在了数据、阈值、业务逻辑和现场调试上,真正写模型训练脚本的时间反而是小头。所以拿到一份像这样质量靠谱的底子数据,后面能省很多事。你完全可以在它的基础上,用自己场景里的少量截图做一次微调,跑通整个“数据→训练→评估→部署”闭环,再一步步迭代扩大样本量,比从零开始爬数据、标数据要快上好几周。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询