news 2026/6/11 11:06:57

工业质检实战:GC10-DET数据集清洗与预处理全流程解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
工业质检实战:GC10-DET数据集清洗与预处理全流程解析

1. GC10-DET数据集深度解析

GC10-DET是工业质检领域一个非常实用的金属表面缺陷数据集,我在多个实际项目中都使用过它。这个数据集最大的特点就是真实——所有样本都来自真实的钢铁生产线,包含了十种常见的表面缺陷类型,总共3570张灰度图像。对于刚接触工业质检的新手来说,这个数据集规模适中,既不会太小导致无法训练模型,也不会太大让数据处理变得困难。

数据集中的十种缺陷类型各有特点:

  • 冲孔(Pu):机械故障导致的非预期孔洞
  • 焊缝(Wl):带钢焊接处产生的痕迹
  • 新月形缝隙(Cg):切割过程中产生的半圆形缺陷
  • 水斑(Ws)油斑(Os):表面污染类缺陷,但视觉特征差异明显
  • 丝斑(Ss):辊压不均匀导致的波浪状斑块
  • 夹杂物(In):金属表面嵌入的异物
  • 轧坑(Rp):周期性隆起或凹陷
  • 折痕(Cr)腰部折痕(Wf):材料变形导致的褶皱

我第一次接触这个数据集时,发现它的组织方式比较特别——图片按缺陷类型存放在10个子文件夹中,而标签则是统一的XML文件。这种结构在实际使用时需要特别注意,因为有些图片可能没有对应的标签文件,这也是我们后续数据清洗的重点之一。

2. 数据清洗全流程实战

2.1 去除无标签样本

在实际项目中,我遇到过不少数据质量问题,其中最常见的就是标签缺失。GC10-DET数据集也不例外,经过检查发现部分图片没有对应的标注文件。这种情况如果不处理,训练时就会遇到麻烦。

我的处理流程是这样的:

  1. 首先创建一个新的项目文件夹,比如GC10-DET_processed
  2. 在里面建立imagesannotations两个子目录
  3. 遍历原始标签文件夹,把所有有效的标签文件名记录下来
  4. 然后逐个检查原始图片,只保留那些有对应标签的图片

这里有个实用技巧:我通常会先用Python的os.listdir()快速检查标签和图片的数量是否匹配。如果发现明显差异,就要仔细检查了。下面是我实际用过的代码:

import os from tqdm import tqdm # 原始数据路径 raw_img_dir = "path/to/raw/images" raw_ann_dir = "path/to/raw/annotations" # 处理后的路径 processed_img_dir = "path/to/processed/images" processed_ann_dir = "path/to/processed/annotations" # 获取所有有效标注文件 valid_files = [f.split('.')[0] for f in os.listdir(raw_ann_dir) if f.endswith('.xml')] # 复制有标注的图片到新目录 for img_file in tqdm(os.listdir(raw_img_dir)): img_name = img_file.split('.')[0] if img_name in valid_files: # 复制图片 shutil.copy( os.path.join(raw_img_dir, img_file), os.path.join(processed_img_dir, img_file) ) # 复制标注 shutil.copy( os.path.join(raw_ann_dir, f"{img_name}.xml"), os.path.join(processed_ann_dir, f"{img_name}.xml") )

2.2 修正错误标签

在数据清洗过程中,我发现GC10-DET存在一些标签错误问题。最常见的是标签名称拼写不一致,比如"10_yaozhe"有时被写成"10_yaozhed"。这类问题看似不大,但在训练时会导致模型无法正确识别这些样本。

我的修正方法是:

  1. 先用grep或Python的glob模块找出所有包含错误标签的XML文件
  2. 然后批量替换错误的标签名
  3. 最后再随机抽查几个文件确认修改是否正确

这里有个坑要注意:Windows和Linux系统的路径表示方法不同,在写脚本时要考虑跨平台兼容性。下面是我使用的修正脚本:

import xml.etree.ElementTree as ET from pathlib import Path def fix_incorrect_labels(xml_dir, wrong_label, correct_label): xml_files = Path(xml_dir).glob("*.xml") for xml_file in xml_files: tree = ET.parse(xml_file) root = tree.getroot() # 查找并修正错误标签 for obj in root.findall("object"): name = obj.find("name") if name.text == wrong_label: name.text = correct_label # 保存修改后的文件 tree.write(xml_file)

3. 数据预处理技巧

3.1 统一数据格式

GC10-DET原始数据是灰度图像,但在实际应用中,我们可能需要将其转换为RGB格式以适应某些预训练模型。我的经验是,简单的灰度转RGB效果往往不如保持原始单通道输入。

我通常会做以下处理:

  1. 图像尺寸标准化:将所有图像调整为相同尺寸
  2. 像素值归一化:将0-255的像素值缩放到0-1范围
  3. 数据增强:针对工业缺陷特点,使用旋转、翻转等增强方式
import cv2 import numpy as np def preprocess_image(img_path, target_size=(512, 512)): # 读取灰度图像 img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) # 调整尺寸 img = cv2.resize(img, target_size) # 归一化 img = img.astype(np.float32) / 255.0 # 可选:转换为3通道 # img = np.stack([img]*3, axis=-1) return img

3.2 数据集划分策略

工业质检数据集的一个特点是样本分布不均衡,某些缺陷类型可能样本很少。我在处理GC10-DET时采用了分层抽样方法,确保每个类别在训练集和验证集中都有代表。

具体步骤:

  1. 按缺陷类别统计样本数量
  2. 对每个类别单独划分训练/验证/测试集
  3. 保持各类别在划分后数据集中的比例一致
from sklearn.model_selection import train_test_split def split_dataset(image_paths, test_size=0.2, random_state=42): # 假设image_paths是包含所有图片路径的列表 # 这里可以根据实际情况获取每个图片的标签 # 分层划分 train_files, val_files = train_test_split( image_paths, test_size=test_size, stratify=labels, # 按标签分层 random_state=random_state ) return train_files, val_files

4. 工程化实践建议

4.1 高效数据加载方案

当数据集较大时,如何高效加载数据是个关键问题。我推荐使用tf.data或PyTorch的DataLoader,它们可以并行加载数据,显著提高训练效率。

这里分享一个我在实际项目中使用的PyTorch数据加载器实现:

from torch.utils.data import Dataset, DataLoader import torch class SteelDefectDataset(Dataset): def __init__(self, img_dir, ann_dir, transform=None): self.img_dir = img_dir self.ann_dir = ann_dir self.transform = transform self.img_files = [f for f in os.listdir(img_dir) if f.endswith('.jpg')] def __len__(self): return len(self.img_files) def __getitem__(self, idx): img_name = self.img_files[idx] img_path = os.path.join(self.img_dir, img_name) # 读取并预处理图像 image = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) image = cv2.resize(image, (512, 512)) image = image.astype(np.float32) / 255.0 image = torch.from_numpy(image).unsqueeze(0) # 增加通道维度 # 读取并解析XML标注 ann_path = os.path.join(self.ann_dir, img_name.replace('.jpg', '.xml')) boxes, labels = parse_xml(ann_path) # 需要实现XML解析函数 if self.transform: image = self.transform(image) return image, {'boxes': boxes, 'labels': labels} # 使用示例 dataset = SteelDefectDataset(img_dir, ann_dir) dataloader = DataLoader(dataset, batch_size=8, shuffle=True, num_workers=4)

4.2 常见问题排查

在数据处理过程中,我遇到过几个典型问题:

  1. 内存不足:处理大尺寸图像时容易发生。解决方案是使用生成器或分块处理。
  2. 标注框越界:有些标注框的坐标可能超出图像范围。需要添加边界检查。
  3. 标签不一致:同一种缺陷可能有不同名称。需要建立统一的标签映射表。

针对标注框越界问题,我通常会添加这样的检查代码:

def check_bbox_validity(box, img_width, img_height): xmin, ymin, xmax, ymax = box # 检查坐标是否在合理范围内 xmin = max(0, min(xmin, img_width - 1)) xmax = max(0, min(xmax, img_width - 1)) ymin = max(0, min(ymin, img_height - 1)) ymax = max(0, min(ymax, img_height - 1)) # 检查是否有效框 if xmin >= xmax or ymin >= ymax: return None return [xmin, ymin, xmax, ymax]

5. 模型训练前的最后检查

在完成所有数据清洗和预处理后,我强烈建议进行以下检查:

  1. 随机可视化一些样本和对应的标注,确认标注正确
  2. 检查训练集和验证集的类别分布是否相似
  3. 确认所有图像都能正常加载,没有损坏文件
  4. 检查数据增强效果是否符合预期

这里分享一个简单的可视化检查代码:

import matplotlib.pyplot as plt import matplotlib.patches as patches def visualize_sample(img_path, ann_path): img = cv2.imread(img_path) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) fig, ax = plt.subplots(1, figsize=(12, 8)) ax.imshow(img) # 解析标注并绘制边界框 boxes, labels = parse_xml(ann_path) for box, label in zip(boxes, labels): xmin, ymin, xmax, ymax = box rect = patches.Rectangle( (xmin, ymin), xmax-xmin, ymax-ymin, linewidth=2, edgecolor='r', facecolor='none' ) ax.add_patch(rect) ax.text(xmin, ymin, label, color='white', backgroundcolor='red') plt.show() # 随机检查几个样本 for _ in range(5): idx = np.random.randint(len(dataset)) img_path = os.path.join(img_dir, dataset.img_files[idx]) ann_path = os.path.join(ann_dir, dataset.img_files[idx].replace('.jpg', '.xml')) visualize_sample(img_path, ann_path)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 11:05:59

告别“大泥球”:我在 Spring Boot 单体架构中实践的模块化隔离

前言:为什么我没选微服务? 经常有同行问我:“你们的网优系统业务这么复杂,为什么不拆微服务?” 我的回答很直接:因为我们的核心痛点不是“并发扩展”,而是“逻辑闭环”。 在电信网络优化领域…

作者头像 李华
网站建设 2026/6/11 11:01:32

题解:AtCoder AT_awc0088_b Bus Tour Group Division

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大…

作者头像 李华
网站建设 2026/6/11 11:01:31

硬件设计笔记:CK6869D蓝牙TWS对箱播放器原理图与PCB布局方案

前言大家好,我是原厂硬件工程师,长期负责蓝牙音频SOC的方案适配、电路标准化设计与TWS对箱产品硬件调试。在便携立体声音频设备中,TWS对箱凭借无线互联、左右声道独立发声、立体声场效果,成为主流消费品类。很多工程师在开发低成本…

作者头像 李华
网站建设 2026/6/11 10:58:42

Typora插件开发指南:从零打造IDE级写作环境

Typora在Markdown编辑器中的地位毋庸置疑。极简的设计、流畅的体验、即时渲染的优雅,让它成为无数技术写作者的首选。但许多用户不知道的是,Typora背后隐藏着一套完整的插件扩展体系。通过这套体系,你可以为Typora添加任何你想要的功能&#…

作者头像 李华