共计 2856 个字符,预计需要花费 8 分钟才能阅读完成。
背景痛点:为什么我们需要更好的标注数据集
在垃圾分类检测任务中,数据质量直接影响模型性能。现有的公开数据集普遍存在以下问题:

- 类别不平衡 :可回收物样本远多于有害垃圾,导致模型对少数类识别率低
- 标注不一致 :不同标注人员对 ” 破碎垃圾 ” 是否算独立物体存在分歧
- 边界模糊 :厨余垃圾常因粘连导致标注框包含背景(如塑料袋)
我们通过 YOLO 格式标注解决这些问题,其优势在于:
- 标准化归一化坐标,便于跨数据集训练
- 文本格式轻量,适合嵌入式设备部署
- 支持矩形框旋转(对倾斜垃圾箱场景重要)
工具对比:主流标注工具横评
LabelImg
- 优点:
- 本地运行无需联网
- 快捷键操作流畅
-
支持 YOLO/PascalVOC 格式导出
-
缺点:
- 无团队协作功能
- 无法处理视频帧
CVAT
- 优点:
- 支持视频逐帧标注
- 内置智能分割工具
-
可分配标注任务给团队成员
-
缺点:
- 需要部署服务器
- 学习曲线较陡
Roboflow
- 优点:
- 在线协同标注
- 内置数据增强流水线
-
支持自动标注建议
-
缺点:
- 免费版有导出次数限制
- 需上传数据到云端
推荐方案 :小型团队选用 LabelImg+Git 版本控制,企业级项目用 CVAT
标注规范:六类垃圾标注细则
类别定义
class_names = [
'recyclable', # 可回收物(如易拉罐)'hazardous', # 有害垃圾(如电池)'kitchen', # 厨余垃圾(如菜叶)'other', # 其他垃圾(如纸巾)'electronic', # 电子废弃物(如手机)'textile' # 纺织物(如旧衣服)]
关键规则
- 遮挡处理 :
- 可见部分 >50%:标完整物体
-
可见部分 <50%:不标注
-
多物体策略 :
- 粘连垃圾:按物理分隔标注多个框
-
套装物品(如盒装牛奶):外包装和内容物分开标注
-
边界判定 :
- 带液体的垃圾:标注到容器边缘
- 松散垃圾(如碎纸):整体视为一个对象
代码实现:从标注到校验全流程
格式转换脚本
import json
import os
def coco2yolo(json_path, output_dir):
"""将 COCO 格式转换为 YOLO 格式"""
with open(json_path) as f:
data = json.load(f)
# 创建类别 ID 映射
cat_id_map = {cat['id']: i for i, cat in enumerate(data['categories'])}
for img in data['images']:
img_id = img['id']
img_w, img_h = img['width'], img['height']
# 筛选当前图片的标注
anns = [a for a in data['annotations'] if a['image_id'] == img_id]
# 生成 YOLO 格式文本
txt_content = []
for ann in anns:
x, y, w, h = ann['bbox']
x_center = (x + w/2) / img_w
y_center = (y + h/2) / img_h
w_norm = w / img_w
h_norm = h / img_h
class_id = cat_id_map[ann['category_id']]
txt_content.append(f"{class_id} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}")
# 写入文件
txt_path = os.path.join(output_dir, f"{img['file_name'].split('.')[0]}.txt")
with open(txt_path, 'w') as f:
f.write('\n'.join(txt_content))
质量校验方法
import cv2
import matplotlib.pyplot as plt
def visualize_annotations(img_path, txt_path):
"""可视化标注框检查错漏"""
img = cv2.imread(img_path)
h, w = img.shape[:2]
with open(txt_path) as f:
lines = f.readlines()
for line in lines:
class_id, xc, yc, bw, bh = map(float, line.strip().split())
# 转换回像素坐标
x1 = int((xc - bw/2) * w)
y1 = int((yc - bh/2) * h)
x2 = int((xc + bw/2) * w)
y2 = int((yc + bh/2) * h)
# 绘制矩形框
color = (0, 255, 0) if class_id == 0 else (0, 0, 255)
cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
数据分布分析
from collections import Counter
import seaborn as sns
def plot_class_distribution(annotations_dir):
"""绘制类别分布直方图"""
class_counts = Counter()
for txt_file in os.listdir(annotations_dir):
with open(os.path.join(annotations_dir, txt_file)) as f:
for line in f:
class_id = int(line.split()[0])
class_counts[class_id] += 1
sns.barplot(x=list(class_counts.keys()),
y=list(class_counts.values())
)
plt.xlabel('Class ID')
plt.ylabel('Count')
plt.title('Class Distribution')
plt.show()
避坑指南:典型错误案例
案例 1:破碎物体标注
错误做法 :将打碎的玻璃瓶标注为多个小物体
正确做法 :视为一个整体标注,添加 ”broken” 属性标签
案例 2:透视变形处理
错误做法 :直接标注倾斜垃圾袋的视觉外轮廓
正确做法 :估计袋口平面后标注直立状态下的矩形
案例 3:阴影误标
错误做法 :将物体阴影包含在标注框内
正确做法 :仅标注实体部分,可通过 HSV 色彩空间分离
性能优化:数据增强策略
实验对比不同增强方法对 mAP 的影响:
- 基础增强 (翻转 + 色变):mAP@0.5=0.73
- Mosaic 增强 :提升小物体检测,mAP@0.5=0.81
- CutMix 增强 :改善类别不平衡,mAP@0.5=0.79
推荐组合策略:
# data_aug.yaml
train:
mosaic: 0.8 # 80% 概率启用
mixup: 0.2
hsv_h: 0.015
hsv_s: 0.7
hsv_v: 0.4
degrees: 10.0
translate: 0.1
开放问题
如何处理垃圾分类中的细粒度子类(如 PET 塑料瓶 vs.PP 塑料盒)?可以考虑:
– 二级分类网络
– 多标签标注体系
– 材质识别辅助模块
期待读者在实践中探索更多解决方案。
正文完
发表至: 未分类
近两天内
