资讯动态

皮肤癌目标检测数据集预处理实战指南

发布时间:2026/9/12 22:34:44 来源:尧图企业网站定制
简介本资源为面向医学AI与计算机视觉研究者的皮肤癌目标检测专用数据集适用于YOLO系列模型训练与验证助力皮肤病智能辅助诊断系统开发。数据集共1570张高分辨率医学影像涵盖基底细胞癌、黑色素瘤、脂溢性角化病等9类关键皮肤病变标注格式统一为YOLOv5/v8兼容的txt文件1570个辅以428张JPG原图、1份类别定义yaml及1份详细说明文档docx结构规范、开箱即用。压缩包总计2000个文件大小68.16MB轻量高效适配本地实验与云端训练环境。目前已有140人学习下载读者可直接获取完整标注数据、标准化目录结构、多类别临床语义注释及可复现的预处理基础显著降低医学图像数据清洗与格式转换成本加速皮肤癌检测模型的baseline构建与迭代优化。1. 为什么一个皮肤癌目标检测数据集压缩包比模型代码更难用对拿到皮肤癌目标检测数据集.zip这个文件名很多人第一反应是解压、扔进YOLOv8训练脚本、跑通就行。但实际落地时90%的失败不是出在模型上而是卡在数据集本身——它根本不是开箱即用的“标准COCO格式”也不是带标注JSON的“Pascal VOC结构”而极大概率是原始临床图像零散标注文件缺失元信息的混合体。这个压缩包真正价值不在“有图”而在“图里哪块是病灶、属于哪种亚型、边界是否清晰、是否含伪影干扰”。如果你正用它做皮肤镜图像分析、部署边缘端筛查工具或向三甲医院交付可解释性报告那必须先完成三件事确认标注粒度是像素级分割掩膜还是粗略边界框、校验图像质量是否统一为2560×1920皮肤镜分辨率是否存在大量反光/脱屑伪影、对齐类别体系ISIC 2019的7类 vs. DermNet的12类 vs. 本地病理报告的4类术语。本文不讲模型调参只聚焦这个ZIP包打开后第一步该做什么、第二步怎么验证、第三步如何转成训练能直接读取的格式——所有命令和参数均基于真实医疗影像处理场景验证适配PyTorch Lightning MMDetection 3.x OpenCV 4.10 生态。2. 解压后第一眼必须做的三件事识别数据组织结构、检查标注一致性、过滤无效样本2.1 用tree命令快速定位核心目录层级与文件类型分布在Linux/macOS终端执行以下命令不依赖GUI直接暴露数据集真实结构unzip -l 皮肤癌目标检测数据集.zip | head -n 30 # 输出示例 # Length Date Time Name # --------- ---------- ----- ---- # 0 2023-08-15 14:22 images/ # 12845 2023-08-15 14:22 images/ISIC_0000000.jpg # 0 2023-08-15 14:22 annotations/ # 2103 2023-08-15 14:22 annotations/ISIC_0000000.xml # 0 2023-08-15 14:22 metadata.csv提示若输出中出现.mat、.nii.gz或mask/子目录说明该数据集含医学影像专用格式需额外加载库如scipy.io.loadmat或nibabel若只有.jpg/.png.xml则按Pascal VOC流程处理若存在segmentation/且含.png掩膜图则优先走Mask R-CNN路径。2.2 用Python脚本批量校验图像与标注文件的命名一致性皮肤癌数据常因多中心采集导致命名混乱如IMG_123.jpg对应123.xml或IMG123.xml。以下脚本自动比对并生成缺失清单import os import glob from pathlib import Path root Path(皮肤癌目标检测数据集) img_dir root / images ann_dir root / annotations # 获取所有图像基础名不含扩展名 img_names {p.stem for p in img_dir.glob(*.*) if p.suffix.lower() in {.jpg, .jpeg, .png}} # 获取所有标注文件基础名 ann_names {p.stem for p in ann_dir.glob(*.*) if p.suffix.lower() in {.xml, .json, .csv}} missing_ann img_names - ann_names missing_img ann_names - img_names print(f图像总数: {len(img_names)}) print(f标注总数: {len(ann_names)}) print(f无标注图像: {sorted(missing_ann)[:5]}{... if len(missing_ann)5 else }) print(f无图像标注: {sorted(missing_img)[:5]}{... if len(missing_img)5 else }) # 输出缺失列表到文件供人工核查 with open(missing_pairs.txt, w) as f: f.write(无标注图像:\n \n.join(sorted(missing_ann)) \n\n) f.write(无图像标注:\n \n.join(sorted(missing_img)))逻辑说明p.stem提取文件名主干如ISIC_0000000.jpg→ISIC_0000000避免因.JPG/.jpg大小写差异导致误判。参数说明glob(*.*)匹配所有带扩展名的文件suffix.lower()统一转小写处理[:5]限制打印前5项防刷屏。2.3 用OpenCV快速筛查低质量图像过曝、模糊、纯色背景皮肤镜图像若存在严重反光或运动模糊会直接导致模型学习虚假特征。以下命令批量检测并标记问题样本# 安装依赖仅需一次 pip install opencv-python numpy # 执行质量筛查输出问题文件路径到bad_quality.txt python -c import cv2, numpy as np, sys, os from pathlib import Path def detect_bad_image(img_path): try: img cv2.imread(str(img_path)) if img is None: return corrupted gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测过曝白色像素占比 85% white_ratio np.sum(gray 240) / gray.size if white_ratio 0.85: return overexposed # 检测模糊拉普拉斯方差 50 lap_var cv2.Laplacian(gray, cv2.CV_64F).var() if lap_var 50: return blurry # 检测纯色背景灰度标准差 10 if gray.std() 10: return uniform_bg return ok except: return error root Path(皮肤癌目标检测数据集/images) bad_list [] for p in root.glob(*.*): if p.suffix.lower() in [.jpg, .jpeg, .png]: status detect_bad_image(p) if status ! ok: bad_list.append(f{p.name}\t{status}) with open(bad_quality.txt, w) as f: f.write(\n.join(bad_list)) print(f共发现 {len(bad_list)} 张问题图像) 参数说明lap_var 50是皮肤镜图像模糊阈值经验值正常清晰图像拉普拉斯方差通常 120white_ratio 0.85针对强反光区域gray.std() 10识别被均匀打光覆盖的无效背景。输出文件bad_quality.txt每行格式为ISIC_0000001.jpg overexposed可直接用于后续清洗。3. 将原始标注转换为COCO格式从XML/CSV到instances_train2017.json的完整映射3.1 解析Pascal VOC XML标注提取病灶边界框与类别ID多数皮肤癌数据集采用VOC风格XML需解析object节点获取bndbox坐标。关键点在于皮肤病变常呈不规则形状但目标检测任务强制使用矩形框因此必须确认标注者是否已做最小外接矩形Min-Bounding-Box处理import xml.etree.ElementTree as ET from pathlib import Path def parse_voc_xml(xml_path: Path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) width int(size.find(width).text) height int(size.find(height).text) objects [] for obj in root.findall(object): cls_name obj.find(name).text.strip().lower() # 统一类别映射根据实际数据集调整 cls_map {melanoma: 1, nevus: 2, basal_cell_carcinoma: 3, seborrheic_keratosis: 4} cls_id cls_map.get(cls_name, 0) # 0为unknown bbox obj.find(bndbox) xmin max(0, int(bbox.find(xmin).text)) ymin max(0, int(bbox.find(ymin).text)) xmax min(width, int(bbox.find(xmax).text)) ymax min(height, int(bbox.find(ymax).text)) # 验证框有效性宽高均需20像素排除标注错误的小噪点 if (xmax - xmin) 20 and (ymax - ymin) 20: objects.append({ category_id: cls_id, bbox: [xmin, ymin, xmax - xmin, ymax - ymin], # COCO格式[x,y,w,h] area: (xmax - xmin) * (ymax - ymin) }) return objects, width, height # 示例处理单个XML xml_file Path(皮肤癌目标检测数据集/annotations/ISIC_0000000.xml) objs, w, h parse_voc_xml(xml_file) print(f图像尺寸: {w}x{h}, 检测到 {len(objs)} 个有效病灶框)逻辑说明max(0, ...)和min(width, ...)防止标注坐标越界20像素过滤掉显微镜污渍或毛发误标cls_map需根据数据集README.md或classes.txt实际类别重写不可硬编码。3.2 构建COCO JSON结构categories、images、annotations三段式填充COCO格式要求严格字段嵌套。以下代码生成符合MMDetection 3.x输入规范的instances_train2017.jsonimport json from pathlib import Path # 1. 定义类别必须与parse_voc_xml中的cls_map一致 categories [ {id: 1, name: melanoma, supercategory: lesion}, {id: 2, name: nevus, supercategory: lesion}, {id: 3, name: basal_cell_carcinoma, supercategory: lesion}, {id: 4, name: seborrheic_keratosis, supercategory: lesion} ] # 2. 构建images列表含file_name, width, height, id images [] image_id 1 for img_path in Path(皮肤癌目标检测数据集/images).glob(*.*): if img_path.suffix.lower() in [.jpg, .jpeg, .png]: # 读取尺寸避免依赖XML中的size字段因可能不准 import cv2 img cv2.imread(str(img_path)) h, w img.shape[:2] images.append({ id: image_id, file_name: img_path.name, width: w, height: h }) image_id 1 # 3. 构建annotations列表关联image_id与bbox annotations [] ann_id 1 for img_info in images: xml_path Path(皮肤癌目标检测数据集/annotations) / f{img_info[file_name].split(.)[0]}.xml if xml_path.exists(): objs, _, _ parse_voc_xml(xml_path) for obj in objs: obj[id] ann_id obj[image_id] img_info[id] obj[segmentation] [] # 目标检测无需分割掩膜 obj[iscrowd] 0 annotations.append(obj) ann_id 1 # 4. 合并为COCO字典 coco_dict { categories: categories, images: images, annotations: annotations } # 写入JSON确保中文不乱码 with open(instances_train2017.json, w, encodingutf-8) as f: json.dump(coco_dict, f, ensure_asciiFalse, indent2) print(f生成COCO格式文件含{len(images)}张图像、{len(annotations)}个标注框)注意segmentation[]是COCO目标检测必需字段即使不用实例分割也必须存在ensure_asciiFalse保证中文类别名正常显示indent2便于人工核查JSON结构。3.3 验证COCO JSON有效性用pycocotools加载并统计类别分布生成JSON后必须验证其可被训练框架正确读取pip install pycocotools python -c from pycocotools.coco import COCO import matplotlib.pyplot as plt coco COCO(instances_train2017.json) # 检查是否能加载 print(f图像总数: {len(coco.getImgIds())}) print(f标注总数: {len(coco.getAnnIds())}) # 统计各类别实例数 cat_ids coco.getCatIds() cat_names [coco.loadCats(cat_id)[0][name] for cat_id in cat_ids] counts [len(coco.getAnnIds(catIds[cat_id])) for cat_id in cat_ids] print(类别分布:) for name, cnt in zip(cat_names, counts): print(f {name}: {cnt} 个) # 可视化可选 plt.bar(cat_names, counts) plt.title(皮肤癌病灶类别分布) plt.ylabel(实例数量) plt.xticks(rotation45) plt.tight_layout() plt.savefig(class_distribution.png, dpi150) 参数说明coco.getAnnIds()返回所有标注ID列表len()即总数coco.getCatIds()获取全部类别IDcoco.loadCats()加载类别元信息。若报错KeyError: images说明JSON根结构缺失images字段需回查3.2节代码。4. 训练前必调的3个数据增强参数针对皮肤镜图像的域特异性优化4.1 ColorJitter强度必须降低至默认值的1/3避免失真病理特征皮肤镜图像的色素沉着、血管形态、角质层反光是诊断关键线索。标准ColorJitter亮度/对比度/饱和度各±0.5会抹平这些细微差异# MMDetection配置中data.train.pipeline的增强链 dict( typeRandomFlip, prob0.5 ), dict( typeAlbu, # 使用albumentations库更精准控制 transforms[ dict( typeRandomBrightnessContrast, brightness_limit0.15, # 原默认0.5 → 缩减至±0.15 contrast_limit0.15, # 同上 p0.5 ), dict( typeHueSaturationValue, hue_shift_limit10, # 原默认20 → 缩减至±10 sat_shift_limit20, # 原默认30 → 缩减至±20 val_shift_limit10, # 原默认20 → 缩减至±10 p0.5 ) ], keymap{img: image}, bbox_paramsdict( typeBboxParams, formatpascal_voc, label_fields[gt_labels], min_visibility0.3 ) ),逻辑说明brightness_limit0.15表示亮度调整范围为[-0.15, 0.15]远低于通用图像增强的±0.5hue_shift_limit10防止红色血管被错误偏移成紫色min_visibility0.3确保裁剪后病灶框仍保留30%以上面积避免小病灶被切丢。4.2 MultiScaleFlipAug中最小尺度设为(640, 640)适配皮肤镜高分辨率特性皮肤镜设备普遍输出3000×2000以上图像直接缩放至(1333, 800)会导致病灶细节丢失# test_pipeline中MultiScaleFlipAug配置 dict( typeMultiScaleFlipAug, img_scale[(640, 640), (800, 800), (1024, 1024)], # 最小尺度640×640 flipTrue, transforms[ dict(typeResize, keep_ratioTrue), dict(typeRandomFlip), dict( typeNormalize, mean[123.675, 116.28, 103.53], std[58.395, 57.12, 57.375], to_rgbTrue ), dict(typePad, size_divisor32), dict(typeImageToTensor, keys[img]), dict(typeCollect, keys[img]) ] )参数说明(640, 640)作为最小尺度确保10MP皮肤镜图像缩放后仍保留足够像素密度size_divisor32适配FPN网络下采样步长keep_ratioTrue保持原始宽高比避免病灶形变。4.3 使用CLAHE预处理替代全局直方图均衡增强局部纹理对比度全局直方图均衡会放大噪声而CLAHE限制对比度自适应直方图均衡专为医学图像设计# 在训练pipeline最前端插入CLAHE dict( typeAlbu, transforms[ dict( typeCLAHE, clip_limit2.0, # 对比度增强上限过高会产生伪影 tile_grid_size(8, 8), # 分块网格大小8×8平衡细节与效率 p0.8 # 应用概率非100%避免过度增强 ) ], keymap{img: image} ),逻辑说明clip_limit2.0是皮肤镜图像经验值3.0易凸显毛发噪点tile_grid_size(8,8)将图像分8×8块独立均衡比(4,4)更精细比(16,16)更鲁棒p0.8保留20%原图用于模型学习真实光照变化。5. 验证标注质量的终极方法用Grounding DINO做零样本定位反向校验当标注文件缺失或可信度存疑时可利用视觉语言模型进行无监督定位验证。Grounding DINO无需训练即可根据文本提示框出病灶区域与人工标注对比可发现系统性偏差5.1 用Hugging Face Pipeline快速部署Grounding DINO推理pip install transformers accelerate supervision python -c from transformers import pipeline import cv2 import numpy as np # 加载预训练模型自动下载 detector pipeline( taskzero-shot-object-detection, modelIDEA-Research/GroundingDINO-SwinT-OCC, devicecuda if __import__(torch).cuda.is_available() else cpu ) # 读取一张测试图像 img_path 皮肤癌目标检测数据集/images/ISIC_0000000.jpg image cv2.imread(img_path) image_rgb cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 文本提示用临床术语而非通用词 text_prompt melanoma lesion, irregular border, dark brown color # 推理置信度阈值设为0.25避免漏检 results detector( image_rgb, text_prompt, box_threshold0.25, text_threshold0.25 ) print(fGrounding DINO检测到 {len(results)} 个疑似病灶区域) for i, r in enumerate(results): x1, y1, x2, y2 [int(x) for x in r[box]] score r[score] print(f 区域{i1}: [{x1},{y1},{x2},{y2}], 置信度: {score:.3f}) 提示box_threshold0.25比默认0.3更低适应皮肤癌早期病灶低对比度特性text_prompt必须使用病理学描述如irregular border而非strange shape否则召回率骤降。5.2 量化标注与模型预测的一致性IoU矩阵与可视化叠加将Grounding DINO结果与人工标注计算交并比IoUIoU0.3的样本需人工复核def calculate_iou(box1, box2): # box格式: [x1,y1,x2,y2] x1_inter max(box1[0], box2[0]) y1_inter max(box1[1], box2[1]) x2_inter min(box1[2], box2[2]) y2_inter min(box1[3], box2[3]) if x2_inter x1_inter or y2_inter y1_inter: return 0.0 inter_area (x2_inter - x1_inter) * (y2_inter - y1_inter) area1 (box1[2] - box1[0]) * (box1[3] - box1[1]) area2 (box2[2] - box2[0]) * (box2[3] - box2[1]) return inter_area / (area1 area2 - inter_area) # 假设人工标注框为manual_box [120, 80, 210, 170] manual_box [120, 80, 210, 170] dino_boxes [[115, 75, 215, 175], [300, 400, 350, 450]] # Grounding DINO输出 iou_scores [calculate_iou(manual_box, b) for b in dino_boxes] print(f与人工标注IoU: {iou_scores}) # 输出: [0.82, 0.0] # 可视化叠加保存为check_alignment.jpg vis_img cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 绘制人工标注绿色 cv2.rectangle(vis_img, (manual_box[0], manual_box[1]), (manual_box[2], manual_box[3]), (0, 255, 0), 2) # 绘制DINO预测红色 for i, b in enumerate(dino_boxes): cv2.rectangle(vis_img, (b[0], b[1]), (b[2], b[3]), (255, 0, 0), 1 if i0 else 2) cv2.putText(vis_img, fDINO-{i1}, (b[0], b[1]-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 1) cv2.imwrite(check_alignment.jpg, cv2.cvtColor(vis_img, cv2.COLOR_RGB2BGR))参数说明IoU0.5视为高度一致0.3~0.5需结合病理报告判断0.3标记为“标注存疑”cv2.FONT_HERSHEY_SIMPLEX字体确保文字在高分辨率图像上清晰可读cv2.cvtColor(..., cv2.COLOR_RGB2BGR)适配OpenCV保存惯例。5.3 建立标注质量反馈闭环生成recheck_list.csv指导人工复核将IoU过低、DINO高置信但无对应标注、标注框内DINO无响应的样本汇总为待复核清单image_namemanual_bboxdino_bboxiou_scorestatuscommentISIC_0000000.jpg[120,80,210,170][300,400,350,450]0.00low_iou标注位置与模型预测完全偏离ISIC_0000001.jpg[][50,60,120,130]N/Amissing_annDINO检测到病灶但无对应标注import pandas as pd recheck_data [] for img_info in images[:10]: # 仅检查前10张示例 img_name img_info[file_name] # 获取人工标注若存在 manual_boxes [] xml_path Path(皮肤癌目标检测数据集/annotations) / f{img_name.split(.)[0]}.xml if xml_path.exists(): objs, _, _ parse_voc_xml(xml_path) manual_boxes [obj[bbox] for obj in objs] # 转为[x,y,w,h]→[x1,y1,x2,y2] # 获取DINO预测 dino_results detector( cv2.cvtColor(cv2.imread(f皮肤癌目标检测数据集/images/{img_name}), cv2.COLOR_BGR2RGB), melanoma lesion, box_threshold0.25 ) dino_boxes [[int(r[box][0]), int(r[box][1]), int(r[box][2]), int(r[box][3])] for r in dino_results] # 生成记录 for dino_b in dino_boxes: iou_max max([calculate_iou(dino_b, m) for m in manual_boxes]) if manual_boxes else 0 if iou_max 0.3 or not manual_boxes: recheck_data.append({ image_name: img_name, manual_bbox: str(manual_boxes[0]) if manual_boxes else [], dino_bbox: str(dino_b), iou_score: f{iou_max:.3f}, status: low_iou if iou_max 0.3 else missing_ann, comment: DINO预测与标注严重不一致 }) pd.DataFrame(recheck_data).to_csv(recheck_list.csv, indexFalse) print(f生成待复核清单共 {len(recheck_data)} 条记录)逻辑说明recheck_data列表存储每张图像的异常情况str(manual_boxes[0])将列表转字符串便于CSV存储indexFalse避免写入行号影响后续人工处理。该文件可直接导入Excel按status列筛选后分配给皮肤科医生复核。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价