工业视觉实战:从零构建YOLOv5齿轮型号识别数据集全流程

发布时间:2026/9/4 22:00:27
工业视觉实战:从零构建YOLOv5齿轮型号识别数据集全流程 简介本资源是一套专为工业视觉检测场景设计的齿轮型号识别目标检测数据集面向YOLOv5算法学习者、智能制造领域开发者及自动化质检项目实践者解决齿轮类小目标在复杂背景下的精准定位与分类问题。数据集严格遵循YOLOv5目录结构组织含3861张训练图像、351张验证图像与174张测试图像每图配对应txt标注文件共1999个采用归一化相对坐标格式classes, x_center, y_center, w, h类别明确划分为B65、B6H、BPN三类另附1个可视化脚本show.py支持一键加载任意图片并绘制带标签的边界框便于快速验证标注质量与模型输出效果。资源共2000个文件总大小332.01MB结构清晰、开箱即用。目前已有135人学习下载适合YOLOv5入门实战、工业缺陷检测迁移训练及数据预处理流程复现。1. 项目概述从零构建一个工业齿轮型号识别数据集最近在做一个工业视觉质检相关的项目核心需求是要能自动识别传送带上不同型号的齿轮并判断其型号是否正确、安装有无缺失。市面上通用的目标检测数据集比如COCO、VOC显然无法满足这种高度定制化的工业场景。于是从零开始构建一个专用于齿轮型号识别的YOLOv5格式数据集就成了项目启动的第一步。这个过程听起来只是“收集图片、打标签”但实际做下来从数据采集、标注规范制定到数据集划分、格式转换每一步都有不少门道。今天我就把这次构建“齿轮型号识别目标检测数据集”的全过程包括踩过的坑和总结的经验详细拆解一遍。无论你是正在做工业缺陷检测、零件分类还是任何需要自定义数据集的视觉项目这套方法论都能直接套用。这个数据集最终包含3个具体的齿轮类别并严格按照YOLOv5要求的目录格式划分了训练集和验证集。选择YOLOv5格式是因为它目前在实际工业部署中依然非常流行生态成熟从训练到部署到各种边缘设备比如RK3568、RV1106的路径都很清晰。接下来我会先带你理清构建一个高质量数据集的核心思路然后深入到图片采集、标注工具选择、格式处理、以及划分策略等每一个实操环节。2. 数据集核心设计思路与前期规划在动手收集第一张图片之前清晰的规划能避免后期大量的返工。我们的目标是“齿轮型号识别”这本质上是一个多类别的目标检测任务。但和识别“猫狗”不同工业零件识别有它的特殊性。2.1 需求拆解与类别定义首先要明确“型号识别”的具体含义。在我们的场景中流水线上会流过A、B、C三种型号的齿轮。它们外观相似但齿数、模数或中心孔尺寸有细微差别。因此我们的三个类别就直接定义为gear_A,gear_B,gear_C。这里的关键点在于类别的定义必须无歧义且覆盖所有需要区分的状态。我们曾考虑过增加一个“齿轮”的通用类别但后来发现这会让模型困惑不利于学习型号间的细微差异。所以直接、具体的类别定义是第一步。其次要思考数据需要覆盖哪些场景。工业环境下的变量很多光照变化车间灯光可能不均匀或有自然光从窗户射入。拍摄角度摄像头固定但传送带上的齿轮可能以任意角度出现。遮挡与密集齿轮可能部分被油污遮挡或多个齿轮堆叠在一起。背景干扰传送带背景、工人手套、工具等都可能入镜。类内差异同型号齿轮因生产批次不同颜色或表面纹理可能有细微差别。我们的数据集必须尽可能地覆盖这些情况模型在应用时才会稳健。这就是常说的“数据分布”要接近“真实分布”。2.2 数据采集方案制定基于以上分析我们制定了数据采集方案设备使用一台2000万像素的工业相机搭配环形光源以减少反光和阴影。模拟流水线环境将相机固定在传送带上方。采集方式摆拍初期将三种齿轮单独、整齐地放在背景板上从正面、侧面、斜45度等多个角度拍摄获取高质量、无遮挡的基准图像。这部分数据用于让模型“认识”齿轮的基本特征。动态抓拍启动传送带随机放入齿轮模拟真实流水线节奏进行抓拍。这时会得到有轻微运动模糊、位置随机、偶尔有遮挡的图像。引入干扰故意在齿轮上涂抹少量油脂模拟油污或撒上一些金属碎屑作为背景干扰。数量目标初期目标每个类别收集500-800张原始图像。这是一个平衡点既能提供一定的学习样本又不会给初期标注带来过大压力。YOLOv5在小数据集上也有不错的表现关键在于数据质量。注意采集时务必记录或生成一个简单的元数据表至少包含文件名、对应的真实型号A/B/C。这个表格在后续的标注和校验环节是救命稻草能有效防止标注类别张冠李戴。3. 数据标注实战工具、规范与质量控制图片有了接下来就是最耗时但也最关键的环节——标注。标注的质量直接决定了模型性能的天花板。3.1 标注工具选型LabelImg vs. CVAT我们对比了两种主流工具LabelImg老牌、轻量、离线的标注工具支持PASCAL VOC和YOLO格式。优点是简单快捷无需配置环境适合小团队或个人快速启动。缺点是功能相对单一缺乏团队协作和审核流程。CVAT英特尔开源的在线标注系统功能强大。支持团队分工作业、审核、自动标注需要初始模型、视频标注等。对于数据量较大或团队协作的项目CVAT是更专业的选择。考虑到项目初期数据量不大且希望流程简单我们选择了LabelImg。它的YOLO格式输出与我们的目标完全一致。3.2 标注规范制定SOP没有统一的规范标注结果会惨不忍睹。我们制定了严格的标注SOP要求所有标注人员遵守框体紧密度边界框必须紧贴齿轮的外缘既不能留太多空隙也不能切掉齿轮本体。对于不规则形状用矩形框住其最小外接矩形。(此处应为示意图描述框体紧贴目标)完整性只要齿轮在图中可见部分超过60%就必须标注。对于严重遮挡可见部分30%的舍弃不标避免引入噪声。类别准确性对照元数据表确保每个框的类别标签绝对正确。这是最高优先级事项。歧义处理对于难以判断型号的模糊图像标注员需提交给项目经理或资深工程师裁定而不是自行猜测。标签文件命名保存的标签文件.txt必须与图片文件同名一一对应。3.3 标注过程与质量控制我们采用“一人标注一人校验”的流程。标注员完成一批数据后校验员会随机抽查至少30%的图片检查框体位置、类别是否正确。如果发现错误率超过5%例如抽查100个框错5个以上则整批数据退回重标。在标注过程中我们遇到了几个典型问题及解决方案问题1反光导致边缘不清。环形光源下齿轮边缘有时会有高光。我们的原则是以可见的实体边缘为准忽略光晕。问题2齿轮齿隙是否要框进经过讨论我们决定框体应包含完整的齿顶圆轻微切入齿隙是可以接受的因为我们的目标是识别型号而非精确分割齿形。问题3标注疲劳导致框体变松。这是人的生理局限。我们要求标注员每工作45分钟必须休息并定期轮换任务。4. YOLOv5数据集目录构建与格式详解标注完成后得到了一堆.jpg图片和对应的.txt标签文件。接下来要把它们组织成YOLOv5能够直接识别的标准格式。4.1 标准目录结构解析YOLOv5期望的目录结构非常清晰这也是其生态优势之一。我们的数据集最终结构如下gear_detection_dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ ├── 000002.jpg │ │ └── ... │ └── val/ │ ├── 000501.jpg │ ├── 000502.jpg │ └── ... └── labels/ ├── train/ │ ├── 000001.txt │ ├── 000002.txt │ └── ... └── val/ ├── 000501.txt ├── 000502.txt └── ...关键点images和labels目录同级且命名必须准确。这是YOLOv5代码默认寻找的路径。train和val子目录名称必须一致。images/train里的图片其标签一定在labels/train里且文件名一一对应。绝对路径 vs. 相对路径在YOLOv5的配置文件中我们通常使用相对于项目根目录的相对路径来指定数据集位置这样便于项目迁移。4.2 标签文件.txt格式深度解读每个.txt文件对应一张图片其内容可能有多行对应多个目标也可能为空无目标。每一行代表一个目标实例格式为class_id x_center y_center width heightclass_id类别的整数索引从0开始。例如我们定义0: gear_A,1: gear_B,2: gear_C。x_center,y_center,width,height目标框中心点的x、y坐标以及框的宽度和高度。这些值都是归一化后的即相对于图片宽度和高度的比例值范围在[0, 1]之间。计算示例 假设一张图片宽img_w 640像素高img_h 480像素。我们标注了一个齿轮其矩形框的左上角像素坐标为(x_min100, y_min60)右下角坐标为(x_max300, y_max180)。计算绝对中心坐标和宽高bbox_w 300 - 100 200bbox_h 180 - 60 120x_center_abs 100 200/2 200y_center_abs 60 120/2 120归一化x_center 200 / 640 0.3125y_center 120 / 480 0.25width 200 / 640 0.3125height 120 / 480 0.25如果这个齿轮是gear_Bclass_id1那么这一行标签就是1 0.3125 0.25 0.3125 0.25重要心得务必编写一个简单的脚本在划分数据集后随机抽样检查一些标签文件验证归一化值是否在[0,1]区间以及class_id是否在定义范围内。我遇到过因为标注工具配置错误导致x_center值大于1训练时直接报错的情况。4.3 数据集划分策略与自动化脚本我们采用7:3的比例随机划分训练集和验证集。验证集用于在训练过程中评估模型性能防止过拟合。划分时有一个黄金原则确保同一个齿轮在不同角度、光照下拍摄的图片必须被分到同一个集合要么全在训练集要么全在验证集。否则模型可能会因为“见过”验证集中某个齿轮的另一个角度而获得虚假的高精度这无法反映其真实的泛化能力。我们根据采集批次session来进行划分而不是完全随机打乱所有图片。例如某次“动态抓拍”采集的150张图要么全部进入训练集要么全部进入验证集。下面是一个使用Python实现的、考虑目录结构的划分脚本import os import random import shutil from pathlib import Path def split_dataset(image_source_dir, label_source_dir, train_ratio0.7): 划分数据集并复制到标准YOLOv5格式目录 :param image_source_dir: 原始图片文件夹路径 :param label_source_dir: 原始标签文件夹路径 :param train_ratio: 训练集比例 # 获取所有图片文件名不含后缀 image_files [f.stem for f in Path(image_source_dir).glob(*.jpg)] random.shuffle(image_files) # 随机打乱 split_idx int(len(image_files) * train_ratio) train_files image_files[:split_idx] val_files image_files[split_idx:] # 创建目标目录结构 base_dir Path(./gear_detection_dataset) (base_dir / images / train).mkdir(parentsTrue, exist_okTrue) (base_dir / images / val).mkdir(parentsTrue, exist_okTrue) (base_dir / labels / train).mkdir(parentsTrue, exist_okTrue) (base_dir / labels / val).mkdir(parentsTrue, exist_okTrue) # 复制文件函数 def copy_files(file_list, subset): for f_name in file_list: # 复制图片 src_img Path(image_source_dir) / f{f_name}.jpg dst_img base_dir / images / subset / f{f_name}.jpg shutil.copy2(src_img, dst_img) # 复制标签 src_lbl Path(label_source_dir) / f{f_name}.txt dst_lbl base_dir / labels / subset / f{f_name}.txt if src_lbl.exists(): shutil.copy2(src_lbl, dst_lbl) else: print(fWarning: Label file {src_lbl} not found, creating empty.) dst_lbl.touch() # 创建空标签文件 copy_files(train_files, train) copy_files(val_files, val) print(fSplit complete. Train: {len(train_files)}, Val: {len(val_files)}) # 使用示例 split_dataset(./raw_images, ./raw_labels, train_ratio0.7)5. 数据增强与预处理考量对于工业数据集尤其是样本量不是特别巨大的情况合理的数据增强是提升模型泛化能力的利器。YOLOv5在训练时内置了强大的数据增强功能通过hyp.scratch.yaml或自定义hyp文件配置但我们也可以在数据集准备阶段进行一些预处理。5.1 适用于工业场景的数据增强策略YOLOv5默认的增强包括Mosaic四图拼接、随机仿射变换旋转、缩放、平移、色彩空间调整HSV抖动等。对于齿轮识别我们需要有选择地启用或调整几何变换旋转齿轮是圆形物体360度旋转是有意义的。可以启用较大角度的随机旋转例如±45度。缩放模拟相机距离变化非常有用。剪切轻度剪切可以增加鲁棒性但不宜过度以免齿轮形状失真过大。色彩与亮度变换HSV抖动可以模拟车间灯光色温变化和亮度波动。但要注意如果齿轮型号的区分特征包含特定颜色例如A型是蓝色涂层B型是银色则色相H抖动要调小或关闭以免混淆类别。高斯噪声可以模拟传感器噪声增强模型抗干扰能力。Mosaic增强对于小目标检测非常有效它能在一个画面中提供更多的上下文信息。对于我们的齿轮数据集Mosaic可以帮助模型学习在复杂、密集背景下识别目标。5.2 预处理空标签与错误标签清洗在划分数据集后正式训练前必须进行一轮数据清洗空标签检查确认labels/val和labels/train目录下是否存在只有图片没有标签或标签文件为空的图片。对于验证集空标签意味着“图中无目标”这是合法的。但对于训练集如果一张图片被标注了但标签文件为空就需要复核是标注遗漏还是确实无目标。标签一致性检查编写脚本验证每个.txt文件中的class_id是否都在预设范围内0,1,2以及归一化坐标是否越界。一个快速检查命令Linux可以是# 检查labels/train下所有txt文件中的class_id grep -r ^[0-9] ./gear_detection_dataset/labels/train/ | awk {print $1} | sort | uniq -c这能统计出每个类别出现的次数同时也能发现是否存在3,4等非法ID。图像损坏检查用OpenCV或PIL尝试打开每一张图片无法打开的即为损坏文件需移除。6. 配置YOLOv5训练环境与数据集文件数据集准备好后需要让YOLOv5“认识”它。这通过一个配置文件来完成。6.1 创建数据集配置文件.yaml在YOLOv5项目的data目录下或自己创建一个目录新建一个gear_dataset.yaml文件# gear_dataset.yaml # 数据集路径相对于yolov5项目根目录或使用绝对路径 path: ../gear_detection_dataset # 数据集根目录 train: images/train # 训练集图片路径相对于path val: images/val # 验证集图片路径相对于path # 类别数量 nc: 3 # 类别名称列表顺序必须与class_id (0,1,2)对应 names: [gear_A, gear_B, gear_C] # 可选下载地址/说明 # download: https://your-dataset-url.com路径配置详解 这是最容易出错的地方。path指定了数据集的总根目录。train和val是相对于path的路径。假设你的YOLOv5代码克隆在/home/user/yolov5而数据集在/home/user/datasets/gear_detection_dataset那么你有两种配置方式相对路径将gear_dataset.yaml放在yolov5/data/下设置path: ../../datasets/gear_detection_dataset。绝对路径直接设置path: /home/user/datasets/gear_detection_dataset。绝对路径更清晰但迁移项目时需要修改。6.2 验证数据集配置是否正确使用YOLOv5提供的工具脚本进行验证是最稳妥的。在YOLOv5项目根目录下运行python train.py --data data/gear_dataset.yaml --weights yolov5s.pt --epochs 1 --img 640 --batch-size 8这里我们只训练1个epoch目的是快速验证数据能否正确加载。观察命令行输出重点看是否成功读取到了train和val的图片数量。在加载数据时有没有报错例如“找不到图片”、“标签格式错误”等。第一个epoch的训练loss是否开始正常下降虽然只跑1轮但初始下降趋势能说明数据在参与计算。如果一切顺利控制台会显示类似以下信息说明数据集配置成功Dataset: gear_dataset.yaml Train: ../gear_detection_dataset/images/train (1050 images) Val: ../gear_detection_dataset/images/val (450 images) ...7. 从数据到模型训练、验证与结果分析数据集构建的最终目的是为了训练一个可靠的模型。这里简要说明如何利用我们准备好的数据集进行训练和初步验证。7.1 启动训练与关键参数解读一个基础的训练命令如下python train.py \ --data data/gear_dataset.yaml \ --weights yolov5s.pt \ --epochs 100 \ --img 640 \ --batch-size 16 \ --workers 4 \ --name gear_detection_exp1--weights yolov5s.pt使用预训练的YOLOv5s模型权重进行迁移学习。这是强烈推荐的做法能极大加快收敛速度提升小数据集上的性能。yolov5s是体积最小、速度最快的版本适合作为起点。--epochs 100训练轮数。需要根据loss曲线和验证集指标mAP是否收敛来决定是否提前停止或增加轮数。--img 640输入图片统一缩放到640x640像素。这是YOLOv5的默认尺寸平衡了速度和精度。--batch-size 16批次大小。取决于你的GPU显存。如果出现CUDA out of memory错误需要调小此值。--workers 4数据加载的线程数用于加速数据读取。--name gear_detection_exp1本次实验的名称所有日志、模型权重都会保存在runs/train/gear_detection_exp1目录下。7.2 监控训练过程与评估指标训练开始后最重要的就是监控几个关键指标损失曲线Loss在runs/train/expX目录下会生成results.png。关注train/box_loss,train/obj_loss,train/cls_loss以及对应的val损失。理想情况是训练损失稳步下降验证损失在后期平稳且与训练损失差距不大。如果验证损失上升可能是过拟合。性能指标Metrics主要是mAP0.5和mAP0.5:0.95。mAP0.5在交并比IoU阈值为0.5时的平均精度均值。这是最常用的一个指标值越高越好对于工业应用通常希望达到0.95以上。mAP0.5:0.95在IoU阈值从0.5到0.95步长0.05区间内的平均mAP是更严格的指标。 这些指标会在验证集上每个epoch结束后计算并记录在results.txt和可视化图表中。7.3 模型验证与错误分析训练完成后使用最佳模型通常是runs/train/expX/weights/best.pt在验证集上进行详细验证python val.py --data data/gear_dataset.yaml --weights runs/train/gear_detection_exp1/weights/best.pt --img 640这个命令会输出详细的评估表格包括每个类别的精确度Precision、召回率Recall、mAP等。重点分析哪个类别的mAP最低可能是该类别样本数量不足或特征与其他类别过于相似。混淆矩阵在runs/val/expX下会生成confusion_matrix.png。查看是否有类别被频繁误判为另一类别。例如如果gear_A经常被误判为gear_B说明这两个型号在视觉上区分度不够可能需要回看数据补充更多能体现差异性的样本如特定角度的特写。8. 常见问题排查与实战心得在整个数据集构建和初步训练过程中我遇到了不少坑这里总结一下希望能帮你绕过去。8.1 标签文件格式错误导致训练报错问题训练时出现ValueError: invalid literal for int() with base 10: 0.1或类似错误。原因标签文件格式不对。最常见的是每行的第一个值class_id不是整数或者后面四个坐标值不是以空格分隔的浮点数。有时从某些标注工具导出的格式是class_id, x, y, w, h逗号分隔而YOLO需要空格分隔。解决写一个格式检查与转换脚本批量处理所有标签文件。确保每行是整数 浮点数 浮点数 浮点数 浮点数且用空格分隔。8.2 图片和标签文件不匹配问题训练能跑但验证时mAP极低或loss不下降。原因images/train中的图片在labels/train中找不到对应的.txt文件或者找到了但内容不对应例如图片是齿轮A标签却是齿轮B的ID。这通常是由于文件命名不一致或复制过程中出错导致的。解决运行一个完整性检查脚本确保每个图片文件都有同名的标签文件并且标签文件非空除非该图片确实无目标。同时可以随机可视化一些样本将标注框画在图片上人工检查是否正确。import cv2 import random from pathlib import Path def visualize_annotation(img_path, label_path, class_names): img cv2.imread(str(img_path)) h, w, _ img.shape with open(label_path, r) as f: lines f.readlines() for line in lines: cls_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) # 画框和标签 cv2.rectangle(img, (x1, y1), (x2, y2), (0,255,0), 2) cv2.putText(img, class_names[int(cls_id)], (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0,255,0), 2) cv2.imshow(Check, img) cv2.waitKey(0) cv2.destroyAllWindows() # 随机检查几张 data_dir Path(./gear_detection_dataset) class_names [gear_A, gear_B, gear_C] train_images list((data_dir / images / train).glob(*.jpg)) for img_path in random.sample(train_images, 5): # 随机看5张 label_path data_dir / labels / train / f{img_path.stem}.txt if label_path.exists(): visualize_annotation(img_path, label_path, class_names) else: print(fLabel missing for {img_path.name})8.3 类别不平衡问题问题三个齿轮型号的样本数量相差很大例如A:800张B:300张C:150张。训练后模型对数量多的类别识别好对数量少的类别识别差。解决数据层面尽可能补充少数类别的数据。如果无法获取可以使用数据增强技术如旋转、裁剪、颜色抖动专门针对少数类别生成更多变体。算法层面YOLOv5的损失函数中包含了类别权重。可以在训练命令中尝试使用--cls_pw参数调整类别权重给少数类别更大的惩罚权重但需谨慎调整建议从1.0微调。 更根本的方法还是从数据源头解决不平衡。8.4 验证集效果虚假“良好”问题训练时验证集mAP很高0.98但实际部署到流水线测试时效果很差。原因这通常是因为验证集和训练集“同源”程度太高没有真正模拟实际场景的复杂性。例如验证集的图片可能只是从训练集同一批采集数据中简单随机分出来的光照、背景、拍摄条件都高度相似。解决严格隔离验证集。确保验证集的数据来自独立的采集会话例如不同日期、不同光线条件下拍摄或者包含更多在训练集中未出现过的干扰情况。让验证集真正扮演“未知数据”的角色这样才能客观评估模型的泛化能力。构建一个高质量的定制化目标检测数据集远不止是体力活。它要求你对业务场景有深刻理解对数据分布有清晰认知并在标注、整理、划分的每一个环节都保持严谨。这份为YOLOv5准备的齿轮型号识别数据集虽然只包含3个类别但贯穿了从需求分析到最终可训练格式交付的完整流程。其中关于标注规范、目录结构、格式校验和划分策略的经验适用于绝大多数工业视觉检测项目。数据是模型的基石这块基石打得越牢后面模型训练和部署的上层建筑才会越稳。本文还有配套的精品资源点击获取