简介:本资源为面向目标检测任务的蜱虫图像数据集,适用于YOLO系列算法训练与验证,可支撑农业监测、公共卫生媒介生物识别等场景的模型开发。数据集已按训练与验证需求划分完毕,并附带data.yaml配置文件,兼容yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流版本,降低环境适配成本。压缩包共2000个文件,包含864个txt格式的YOLO标注与1136个xml格式的VOC标注,两种标签分别存放于独立文件夹,文件名末尾标注类别名称,便于按类别检索与格式转换;YOLO标注采用归一化中心点与宽高比例,符合标准训练输入要求。整体包体约68.19MB,轻量易传输。目前已有87人学习下载,适合需要快速开展蜱虫检测实验、验证模型效果或进行多格式标注对比的研究者与开发者直接使用。
1. 蜱虫图像检测为什么值得单独做一个数据集
1602 张带标签的蜱虫图像,这个量级放在通用目标检测里连零头都算不上,但放在蜱虫这个细分场景里,它已经能撑起一个可用的基线模型。原因很直接:蜱虫检测的难点从来不是「数据不够多」,而是「数据不够对」。蜱虫体型小、颜色和宿主皮肤或草叶高度接近、拍摄时经常处于遮挡或模糊状态,通用数据集里几乎没有这类样本,拿 COCO 预训练权重直接推理,召回率会低到让你怀疑模型是不是没加载成功。
这个数据集解决的就是「从零攒一批能训的蜱虫标注」这件事。1602 张图像带标签,意味着你不需要自己拿 LabelImg 一张张画框,可以直接进入训练和调参环节。适合两类人:一类是做病媒生物监测、野外采样辅助识别的工程团队,想快速验证 YOLO 在这个场景下到底能不能用;另一类是做小目标检测研究的人,想找一个真实的小目标、类不平衡、背景干扰强的数据集来压模型。
我拿到这类数据集的第一反应不是直接开训,而是先做三件事:看标注格式、看类别分布、看图像分辨率分布。这三件事决定了你后面 80% 的调参方向。下面按「先摸清数据 → 再跑通训练 → 再处理坑 → 最后做进阶」的顺序讲。
2. 拿到 1602 张蜱虫图像后先做三件事:格式、分布、分辨率
2.1 确认标注格式是 YOLO txt 还是 VOC XML
标题写的是「带标签」,但没说是哪种标签。实际拿到手最常见的是两种:每张图对应一个同名 .txt 的 YOLO 格式,或者一个 Annotations 文件夹装 XML 的 VOC 格式。这两种处理路径完全不同,先确认再动手。
YOLO txt 每行是class_id x_center y_center width height,坐标全部归一化到 0~1。VOC XML 是绝对像素坐标的xmin ymin xmax ymax。判断方法很简单,解压后看目录结构:
# 查看解压后的目录结构,判断标注格式 find ./tick_dataset -maxdepth 2 -type d | head -20 # 如果看到 labels/ 目录且里面是 .txt,就是 YOLO 格式 # 如果看到 Annotations/ 且里面是 .xml,就是 VOC 格式 ls ./tick_dataset/labels | head -5 head -3 ./tick_dataset/labels/000001.txt如果输出类似0 0.523 0.441 0.062 0.058,就是 YOLO 格式,可以直接用。如果是 XML,需要先转换。转换脚本我一般这么写:
import xml.etree.ElementTree as ET import os # VOC XML 转 YOLO txt,class_map 根据你的类别名调整 def voc_to_yolo(xml_dir, out_dir, class_map): os.makedirs(out_dir, exist_ok=True) for xml_file in os.listdir(xml_dir): if not xml_file.endswith('.xml'): continue tree = ET.parse(os.path.join(xml_dir, xml_file)) root = tree.getroot() size = root.find('size') w = int(size.find('width').text) h = int(size.find('height').text) lines = [] for obj in root.iter('object'): name = obj.find('name').text if name not in class_map: continue cls_id = class_map[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) # 归一化并转为中心点+宽高 x_c = (xmin + xmax) / 2.0 / w y_c = (ymin + ymax) / 2.0 / h bw = (xmax - xmin) / w bh = (ymax - ymin) / h lines.append(f"{cls_id} {x_c:.6f} {y_c:.6f} {bw:.6f} {bh:.6f}") out_name = os.path.splitext(xml_file)[0] + '.txt' with open(os.path.join(out_dir, out_name), 'w') as f: f.write('\n'.join(lines)) voc_to_yolo('./Annotations', './labels', {'tick': 0})这段代码的关键在归一化那四行:中心点坐标除以宽高,宽高也除以宽高。很多人转完发现框全跑到左上角,就是忘了除以图像尺寸。class_map里只保留你真正要检测的类别,VOC 里常有tick、tick_cluster这种多类,如果只做单类检测,统一映射到 0。
2.2 统计类别分布和每张图的框数量
1602 张图里,如果大部分图只有 1 个框,少数图有 10 个以上,那训练时正样本会严重偏向「单目标」模式,模型遇到密集蜱虫就崩。统计一下:
import os from collections import Counter label_dir = './labels' box_per_img = [] cls_counter = Counter() for f in os.listdir(label_dir): if not f.endswith('.txt'): continue with open(os.path.join(label_dir, f)) as fp: lines = [l for l in fp.read().strip().split('\n') if l] box_per_img.append(len(lines)) for l in lines: cls_counter[l.split()[0]] += 1 print('总图数:', len(box_per_img)) print('总框数:', sum(box_per_img)) print('每图平均框数:', sum(box_per_img) / len(box_per_img)) print('每图最大框数:', max(box_per_img)) print('类别分布:', cls_counter)如果每图平均框数低于 1.5,说明大部分是单目标样本,这时候数据增强里的 mosaic 要慎用,mosaic 会把 4 张图拼成 1 张,单目标图拼完变成 4 个目标,分布和真实场景不一致。我一般在这种分布下把 mosaic 概率从默认 1.0 降到 0.3~0.5。
2.3 看分辨率分布决定输入尺寸
蜱虫是小目标,输入尺寸直接决定小目标能不能被检测到。统计一下图像宽高:
from PIL import Image import os sizes = [] for f in os.listdir('./images'): if f.lower().endswith(('.jpg', '.png', '.jpeg')): with Image.open(os.path.join('./images', f)) as im: sizes.append(im.size) ws = [s[0] for s in sizes] hs = [s[1] for s in sizes] print('宽 min/max/mean:', min(ws), max(ws), sum(ws)//len(ws)) print('高 min/max/mean:', min(hs), max(hs), sum(hs)//len(hs))如果原图普遍在 1920×1080 以上,而蜱虫框只有几十像素,直接 resize 到 640 会把蜱虫压成几个像素,模型根本学不到。常见做法是:训练输入用 640 或 960,但对小目标密集的图做切图增强,或者把输入提到 1280。代价是显存和速度,这个后面在参数章节细说。
3. 用 YOLO 在本地跑通蜱虫检测的最小训练流程
3.1 数据集目录组织与 data.yaml 配置
YOLO 系列对目录结构有固定要求,最稳的是这样:
tick_dataset/ images/ train/ val/ labels/ train/ val/ data.yaml划分比例我一般用 8:2,1602 张就是 train 1281、val 321。如果类别极不平衡,用分层抽样,保证 val 里也有足够正样本。data.yaml 内容:
# data.yaml path: ./tick_dataset train: images/train val: images/val nc: 1 names: 0: ticknc是类别数,单类就写 1。names的 key 从 0 开始,和 txt 里的 class_id 对应。这里最容易翻车的是路径:path写相对路径时,是相对于你执行训练命令的工作目录,不是相对于 data.yaml 文件。我习惯写绝对路径,省得后面找不到图。
3.2 训练命令与关键参数含义
最小可跑命令:
yolo detect train \ data=./tick_dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=20 \ project=./runs_tick \ name=exp1逐项说:model=yolov8n.pt是最小的 nano 模型,先跑通再换 s/m。imgsz=640是输入尺寸,小目标场景可以提到 960 或 1280,但 batch 要相应降到 8 或 4。lr0=0.01是初始学习率,小数据集上 0.01 偏大,容易震荡,我一般从 0.001 起。patience=20是 20 轮没提升就早停,防止过拟合。
如果显存不够,优先降 batch,再降 imgsz,最后才考虑换更小的模型。因为 imgsz 降了,小目标直接消失,模型再小也没用。
3.3 训练过程中该盯哪几个指标
训练日志里指标很多,蜱虫检测重点看三个:metrics/mAP50、metrics/mAP50-95、val/box_loss。mAP50 涨但 mAP50-95 不涨,说明框的位置不够准,蜱虫框小,几个像素的偏差就掉很多 IoU。val/box_loss 持续下降但 mAP 不涨,通常是过拟合,看 train/box_loss 和 val/box_loss 的差距。
还有一个容易被忽略的:metrics/precision和metrics/recall。蜱虫检测里 recall 比 precision 重要,漏检一只蜱虫的代价远大于多报一个。如果 recall 明显低于 precision,调低置信度阈值,或者检查标注里有没有漏标。
4. 蜱虫小目标检测的避坑与排查清单
4.1 现象:训练 loss 正常下降,但验证集 mAP 一直是 0
原因通常有三个:标注格式不对、类别 id 对不上、图像和标签文件名不匹配。YOLO 是按文件名找标签的,images/train/abc.jpg必须对应labels/train/abc.txt,差一个字符就当成无标签图,全算背景。
解决:写个校验脚本,遍历 images 下每个文件,检查对应 labels 是否存在、每行是否 5 个字段、坐标是否在 0~1 之间。
import os def check_pair(img_dir, lbl_dir): bad = [] for f in os.listdir(img_dir): stem = os.path.splitext(f)[0] lbl = os.path.join(lbl_dir, stem + '.txt') if not os.path.exists(lbl): bad.append(('missing_label', f)) continue with open(lbl) as fp: for i, line in enumerate(fp): parts = line.strip().split() if len(parts) != 5: bad.append(('bad_fields', f, i)) continue vals = [float(x) for x in parts[1:]] if any(v < 0 or v > 1 for v in vals): bad.append(('out_of_range', f, i)) return bad print(check_pair('./images/train', './labels/train')[:20])4.2 现象:模型把背景里的斑点、污渍也框成蜱虫
原因:负样本(无蜱虫的背景图)太少,或者背景图和蜱虫图差异太大,模型没学会区分。1602 张里如果全是带蜱虫的图,没有纯背景图,模型会把「像蜱虫的深色斑点」都当目标。
解决:从原图里裁一些无目标的区域作为背景图加入训练,比例控制在 5%~10%。或者用 hard negative mining:先用训好的模型跑一遍训练集,把误检高的背景图挑出来,加入负样本再训一轮。
4.3 现象:小蜱虫漏检严重,大蜱虫检得还行
原因:小目标在特征图上占的像素太少,经过多次下采样后特征消失。这是 YOLO 在小目标上的固有问题,不是调参能完全解决的。
解决:提高输入尺寸到 960 或 1280;在数据增强里加scale=0.5让目标变大;如果用的是 YOLOv8,可以试copy_paste增强,把小目标复制粘贴到其他位置增加正样本密度。代价是训练时间翻倍。
4.4 现象:换了更大的模型,mAP 反而降了
原因:数据集只有 1602 张,大模型参数量大,直接过拟合。或者大模型的默认学习率和 batch 不匹配。
解决:大模型配更小的学习率(比如 0.001 降到 0.0005),加更强的正则(dropout、weight_decay),或者先用小模型确定数据没问题,再换大模型微调。我一般先用 nano 跑通,确认 mAP 能到 0.6 以上,再换 s 或 m。
4.5 现象:验证集 mAP 很高,但实际拍的新图检测效果差
原因:训练集和验证集来自同一批拍摄条件,验证集不能反映真实分布。蜱虫检测里,拍摄角度、光照、宿主皮肤颜色变化很大,如果数据集里全是某一种背景,模型就学偏了。
解决:手动留出一批不同来源的图做测试集,不参与训练和验证。如果 mAP 在测试集上掉超过 20 个点,说明数据多样性不够,需要补数据或做更强的颜色、亮度增强。
5. 把 1602 张用到极致:小目标增强与推理调优的两个技巧
5.1 切图训练:把大图切成小图再训
蜱虫在原图里可能只占 30×30 像素,整图 resize 到 640 后只剩 10×10。切图训练的思路是:把原图按 640×640 滑窗切,重叠 20%,每块单独作为训练样本。这样蜱虫在切块里的相对尺寸变大,模型更容易学到特征。
from PIL import Image import os def slice_image(img_path, out_dir, slice_size=640, overlap=128): im = Image.open(img_path) w, h = im.size step = slice_size - overlap idx = 0 for y in range(0, h, step): for x in range(0, w, step): box = (x, y, min(x+slice_size, w), min(y+slice_size, h)) crop = im.crop(box) # 小于 slice_size 的块补边,避免尺寸不一致 if crop.size != (slice_size, slice_size): canvas = Image.new('RGB', (slice_size, slice_size), (114,114,114)) canvas.paste(crop, (0, 0)) crop = canvas crop.save(os.path.join(out_dir, f"{os.path.splitext(os.path.basename(img_path))[0]}_{idx}.jpg")) idx += 1切完之后标签也要同步切,逻辑是按切块坐标裁剪框,超出边界的框截断或丢弃。这一步容易出错,建议切完先可视化几张确认框和蜱虫对齐。切图训练的代价是样本量翻几倍,训练时间增加,但小目标召回通常能涨 10~20 个点。
5.2 推理阶段调低置信度 + NMS 参数
训练完导出模型后,推理时的conf和iou两个参数对最终效果影响很大。蜱虫检测我一般这样设:
yolo detect predict \ model=./runs_tick/exp1/weights/best.pt \ source=./test_images \ conf=0.15 \ iou=0.5 \ imgsz=960 \ save=Trueconf=0.15比默认的 0.25 低,目的是提高召回,宁可多框几个也别漏。iou=0.5是 NMS 的阈值,蜱虫密集时如果框重叠多,调高到 0.6 保留更多框。imgsz=960比训练时的 640 大,推理时提高分辨率对小目标有帮助,代价是速度下降。
验证这套参数是否有效,不能只看 mAP,要拿一批实际场景图跑一遍,人工数漏检和误检。我自己的习惯是:每次调完参数,固定抽 50 张图,记录漏检数和误检数,做成表格对比。这个习惯帮我避免了很多次「指标涨了但实际更难用」的翻车。
最后说一个我踩过的坑:不要一上来就追求高 mAP。蜱虫检测的最终目标是辅助人工筛查,召回率比精度重要得多。先把 recall 做到 0.9 以上,再慢慢压误检。希望帮到你。
本文还有配套的精品资源,点击获取