基于YOLOv8的中医舌诊目标检测数据集构建与模型训练实战
2026/9/4 4:26:03 网站建设 项目流程

简介:本资源是面向中医智能诊断、医学图像分析及计算机视觉初学者的舌像目标检测专用数据集,聚焦舌头区域五类常见舌苔/舌质表征识别任务。数据集共2000个文件,包含800张高质量舌部JPEG图像、800份Pascal VOC格式XML标注文件(含坐标与类别)及800份YOLO格式TXT标签文件,全部使用labelImg规范标注矩形框,类别明确对应‘bobai’‘fenhong’‘houbai’‘houhuang’‘huihei’五种中医舌象类型,总标注框数达800个,分布均衡,可直接用于YOLOv5/v8、Faster R-CNN等主流检测模型训练与验证。压缩包仅29.84MB,轻量易下载,结构清晰无冗余路径,适配深度学习项目快速启动。目前已有1233人学习下载,提供开箱即用的双格式支持,显著降低数据预处理门槛,助力中医AI方向的课程实验、毕业设计与算法 baseline 构建。

1. 项目概述:一份专为舌诊现代化设计的入门级数据集

最近在整理一些过往的医疗影像分析项目资料时,翻出了一个自己早期搭建的“舌头舌像检测数据集”。这个数据集虽然规模不大,只有800张图片,但麻雀虽小五脏俱全,它严格遵循了VOC和YOLO两种主流格式,并且标注了5个关键的舌象类别。对于刚接触计算机视觉在中医领域应用,或者想快速验证一个目标检测模型效果的朋友来说,这份数据集是个非常不错的“敲门砖”。它避开了动辄数万张图片的庞大体量带来的数据清洗和标注压力,让你能快速跑通从数据准备到模型训练评估的完整流程,把精力集中在理解“舌诊目标检测”这个任务本身。

简单来说,这个数据集的核心价值在于提供了一个标准化的、开箱即用的实验沙箱。无论你是医学影像分析的研究生,还是对AI+传统医学感兴趣的开发者,都可以用它来:

  1. 快速上手:理解VOC和YOLO数据格式的差异与转换。
  2. 模型验证:测试YOLOv5、YOLOv8等主流目标检测算法在特定医学图像上的基础性能。
  3. 任务定义:直观感受“舌体分割”、“舌苔识别”、“瘀点检测”等抽象概念如何被转化为具体的矩形框(Bounding Box)标注问题。
  4. 流程演练:完整走一遍数据加载、增强、训练、验证的Pipeline,为后续处理更大、更复杂的专业舌诊数据集积累经验。

数据集以.7z压缩包格式提供,解压后结构清晰,包含了图像(JPEGImages)、标注(Annotations 和 labels)、以及划分好的训练集/验证集列表文件,确保你拿到手后五分钟内就能让数据加载器跑起来。

2. 数据集深度解析:从格式到类别设计的背后逻辑

2.1 双格式并存:VOC与YOLO的考量与转换实践

这个数据集同时提供了PASCAL VOC格式和YOLO格式的标注,这并非冗余,而是基于不同阶段的使用需求精心设计的。

PASCAL VOC格式以XML文件存储标注信息,其特点是信息完整、可读性强。每个XML文件里,不仅包含了目标物体的类别名称和边界框坐标(xmin, ymin, xmax, ymax),通常还会记录图片的尺寸、深度等信息。这种格式非常适合数据审查、可视化调试和跨平台交换。当你需要肉眼检查标注框是否准确,或者使用一些传统的、基于XML解析的工具链时,VOC格式是首选。在本数据集中,Annotations文件夹下的每一个XML文件都对应一张舌像图片的详细标注。

YOLO格式则是一种归一化的纯文本格式。每个标注文件(.txt)对应一张图片,其中每一行代表一个目标物体,格式为:<class_id> <x_center> <y_center> <width> <height>。这里的坐标和宽高都是相对于图片宽度和高度的比例值(范围0-1)。这种格式的优点是存储紧凑、加载高效,直接被YOLO系列、以及许多其他现代深度学习框架(如PyTorch的TorchVision)所原生支持。在本数据集的labels文件夹中,你可以找到这种格式的标注。

注意:提供双格式意味着使用者需要理解它们之间的转换。虽然很多开源脚本可以互转,但本数据集已为你做好,确保了两种格式标注的一致性。在训练YOLO模型时,请直接使用labels下的txt文件;在进行数据分析或标注修正时,则可以参考VOC的XML文件。

2.2 五类别定义:贴合中医舌诊的核心观察维度

数据集的5个类别是其专业价值的集中体现。它没有试图覆盖舌诊中所有上百种细微变化,而是聚焦于最核心、最易辨识、同时也是算法初期最可能有效学习的几个宏观特征:

  1. 舌体 (Tongue Body):这是检测的基座。几乎每张图片都会包含这个类别,标注框圈出整个舌头的轮廓。识别舌体是第一步,用于定位ROI(感兴趣区域),排除脸部其他部位的干扰。
  2. 白苔 (White Coating):代表寒证或表证。在图像上通常表现为覆盖在舌体表面的一层白色或灰白色区域。标注时,会框选出苔质均匀、颜色显著偏白的部分。
  3. 黄苔 (Yellow Coating):代表热证。颜色从淡黄到焦黄不等。与白苔的标注逻辑类似,但针对黄色区域。一张舌像可能同时存在白苔和黄苔区域,这体现了病情的复杂性。
  4. 瘀斑 (Petechia/Ecchymosis):代表瘀血。在舌面上表现为紫色或暗红色的斑点、斑块。这类目标通常尺寸较小,对检测模型的小目标识别能力是一个考验。
  5. 裂纹 (Fissure):代表阴血亏虚。指舌面上出现的裂纹、沟回。标注时,会用矩形框大致框出裂纹所在的条状区域。由于裂纹形态不规则,用矩形框标注本身就是一种近似和折中。

这样的类别设计,平衡了中医理论指导与计算机视觉实现的可行性。它让算法学习的目标非常具体——不是直接判断“阴虚”或“血瘀”,而是先学会找到“裂纹”或“瘀斑”这些客观存在的视觉证据。这正符合现代AI辅助诊断的研究思路:将复杂的医学诊断问题,拆解为一系列可量化、可检测的视觉特征识别任务。

2.3 数据规模与质量:800张图片的合理性与挑战

800张图片,5个类别,这个规模在工业级检测项目中显然不足,但在教学、原型验证和算法初步探索阶段,这是一个非常务实的规模。

  • 合理性

    • 启动成本低:高质量的医学图像标注成本极高,需要专业中医师参与。800张是一个在可控成本内能保证一定质量的数量。
    • 快速迭代:在小数据集上,模型训练速度快(可能只需几十分钟),方便研究者快速尝试不同的网络结构、超参数和数据增强策略。
    • 聚焦问题:规模有限的数据集迫使使用者更关注数据质量、类别平衡和评估方法的可靠性,而不是盲目追求数据量。
  • 面临的挑战与应对

    • 类别不平衡:“舌体”类别数量最多,“瘀斑”和“裂纹”可能较少。在训练时,需要采用加权损失函数(如Focal Loss)或过采样/欠采样策略来缓解。
    • 样本多样性有限:800张图片可能无法覆盖所有年龄、肤色、拍摄光照条件下的舌象。这会影响模型的泛化能力。解决方案是必须进行强力的数据增强,包括随机旋转、缩放、色彩抖动(调整亮度、对比度、饱和度)、添加高斯噪声等,以模拟真实世界的变化。
    • 标注一致性:舌苔的边缘、小瘀斑的界定可能存在主观差异。数据集提供者应通过多名标注员交叉审核来保证一致性。使用者也可以通过可视化工具随机抽查标注,做到心中有数。

3. 实战:使用YOLOv8训练舌像检测模型全流程

下面,我将以目前最流行的YOLOv8为例,展示如何利用这个数据集完成一个舌像检测模型的训练与评估。假设你已经解压数据集,并整理成如下目录结构(这是YOLO官方推荐的结构):

tongue_dataset/ ├── images/ │ ├── train/ # 存放训练集图片 │ └── val/ # 存放验证集图片 └── labels/ ├── train/ # 存放训练集标签txt文件 └── val/ # 存放验证集标签txt文件

3.1 环境配置与数据准备

首先,创建一个Python虚拟环境并安装依赖。

# 创建并激活虚拟环境(可选,但推荐) python -m venv yolo_tongue source yolo_tongue/bin/activate # Linux/Mac # yolo_tongue\Scripts\activate # Windows # 安装PyTorch (请根据你的CUDA版本前往PyTorch官网选择对应命令) # 例如,对于CUDA 11.8: pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装Ultralytics YOLOv8 pip install ultralytics

接下来,你需要创建一个数据集配置文件tongue.yaml,放在项目根目录。这个文件告诉YOLO你的数据在哪、有哪些类别。

# tongue.yaml path: /path/to/your/tongue_dataset # 数据集的根目录 train: images/train # 训练集图片相对路径 val: images/val # 验证集图片相对路径 # 类别数量 nc: 5 # 类别名称列表,必须与标注文件中的class_id顺序对应(0,1,2,3,4) names: ['tongue_body', 'white_coating', 'yellow_coating', 'petechia', 'fissure']

3.2 模型训练与关键参数解析

使用Ultralytics库,训练一个YOLOv8模型变得异常简单。但理解关键参数至关重要。

from ultralytics import YOLO # 加载一个预训练模型(推荐从COCO数据集预训练的模型开始) model = YOLO('yolov8n.pt') # 这里用最小的nano模型,训练快,适合演示 # 开始训练 results = model.train( data='tongue.yaml', # 数据集配置文件路径 epochs=100, # 训练轮数,对于小数据集,100-150轮通常足够观察趋势 imgsz=640, # 输入图片缩放尺寸,640是常用尺寸 batch=16, # 批次大小,根据你的GPU内存调整。8, 16, 32都是常见值。 workers=4, # 数据加载线程数,用于加速数据读取 device='0', # 使用GPU 0,如果是CPU则设为'cpu' name='tongue_det_v1', # 本次训练的实验名称,用于保存结果 pretrained=True, # 使用预训练权重(强烈推荐) optimizer='AdamW', # 优化器,AdamW是当前主流选择 lr0=0.01, # 初始学习率,这是一个较高的起点,YOLO的调度器会逐渐降低它 cos_lr=True, # 使用余弦退火学习率调度,有助于模型收敛更好 augment=True, # 启用默认的数据增强,对于小数据集这是必须的! # 以下是一些针对小数据集的进阶技巧 # dropout=0.1, # 可以尝试加入少量Dropout防止过拟合 # weight_decay=0.0005, # 权重衰减,正则化项 # mixup=0.1, # MixUp增强比例,轻微使用可以提升泛化性 )

关键参数解读与调优建议:

  • imgsz:舌像图片通常为面部特写,背景相对单一。640x640的分辨率在精度和速度之间取得了良好平衡。如果“瘀斑”这类小目标漏检严重,可以尝试增大到832甚至1024,但会显著增加显存消耗和训练时间。
  • batch:批次大小直接影响梯度下降的稳定性。在GPU显存允许的情况下,尽可能设大一些(如16、32)。如果出现“CUDA out of memory”错误,就减小batchimgsz
  • augment务必保持为True。YOLOv8内置的增强包括Mosaic、随机仿射变换、色彩空间调整等,这是让小数据集“变相”增大的最关键手段。
  • lr0:学习率是超参数调优的核心。0.01对于YOLOv8是常用初始值。如果训练过程中损失(loss)出现NaN(非数)或者剧烈震荡,可以尝试将其降低到0.001或0.005。
  • epochs:训练时密切观察验证集上的mAP50-95(平均精度)曲线。当该指标在连续10-20个epoch内不再上升,甚至开始下降时,就说明模型可能已经过拟合,可以提前停止训练。

3.3 训练过程监控与评估

训练开始后,YOLOv8会在runs/detect/tongue_det_v1目录下生成大量有用信息:

  • weights/:保存最佳模型(best.pt)和最后模型(last.pt)。
  • events.out.tfevents.*:TensorBoard日志文件。使用tensorboard --logdir runs/detect/tongue_det_v1命令启动可视化面板,你可以实时查看损失曲线、精度曲线、验证集预测样例等,这是调试训练过程的“仪表盘”
  • args.yaml:保存本次训练的所有参数,便于复现。
  • results.csv:训练指标的CSV记录。

训练完成后,使用最佳模型在验证集上进行全面评估:

# 在命令行中执行 yolo val model=runs/detect/tongue_det_v1/weights/best.pt data=tongue.yaml

评估报告会输出关键指标,其中你需要重点关注:

  • mAP50-95:这是核心指标,表示在IoU(交并比)阈值从0.5到0.95(步长0.05)下的平均精度均值。值越高,模型整体性能越好。
  • mAP50:IoU阈值为0.5时的平均精度,这是一个更宽松的指标,通常值会更高。
  • precisionrecall:精确率和召回率。对于医学检测,我们往往希望在保证高精确率(减少误报)的前提下,尽可能提高召回率(减少漏报)。你可以通过调整预测时的conf(置信度阈值)来平衡二者。
  • 各类别的AP值:仔细查看5个类别各自的AP值。你可能会发现“舌体”的AP很高(如0.95),而“瘀斑”的AP很低(如0.3)。这直观地反映了类别不平衡问题和小目标检测的难度,为下一步优化指明了方向。

4. 性能优化与部署应用的关键技巧

4.1 针对舌像数据集的优化策略

当你在基础训练完成后发现模型对“瘀斑”、“裂纹”等小目标或难样本检测不佳时,可以尝试以下策略:

  1. 针对性数据增强

    • 小目标增强:专门为“瘀斑”这类小目标复制粘贴增强(Copy-Paste Augmentation),即在图片中随机复制一些小目标并粘贴到合理位置,增加其出现频率。
    • 网格遮挡:使用gridmaskrandom erase增强,随机遮挡图片部分区域,迫使模型不只依赖局部特征,提高对不完整“裂纹”的识别鲁棒性。
  2. 模型层面调整

    • 更换模型尺度:如果你从yolov8n.pt开始,可以尝试更大的模型,如yolov8s.ptyolov8m.pt。更大的模型容量更高,特征提取能力更强,但需要更多数据和更长的训练时间。
    • 修改检测头:YOLOv8的检测头针对通用目标优化。对于小目标,可以尝试减少下采样倍数(修改model.yaml中的stride),或者在Neck部分添加更浅层的特征融合路径(如借鉴FPN+PAN结构),将更高分辨率的浅层特征用于小目标预测。
    • 损失函数调优:默认的损失函数是v8Loss。可以尝试调整其中分类损失(cls_loss)和定位损失(box_loss)的权重,或者引入Focal Loss来更关注难分类的样本。
  3. 后处理优化

    • 非极大值抑制参数:预测时使用的NMS(iou_thresconf_thres)直接影响结果。对于密集的小目标(如多个瘀斑),可以适当降低iou_thres(如从0.7调到0.5),防止重叠目标被错误抑制。
    • 测试时增强:在模型预测时,对输入图像进行多尺度、多翻转的增强,然后将所有预测结果合并,再进行NMS。这能提升精度,但会大幅增加推理时间。

4.2 从模型到应用:轻量化部署与集成

训练出一个满意的模型(.pt文件)只是第一步。要将其用于实际,例如集成到一个移动端舌诊APP或桌面分析软件中,你需要考虑部署。

  1. 模型导出:YOLOv8支持一键导出为多种格式。

    from ultralytics import YOLO model = YOLO('runs/detect/tongue_det_v1/weights/best.pt') model.export(format='onnx') # 导出为ONNX格式,广泛支持 # model.export(format='tflite') # 导出为TFLite格式,用于移动端 # model.export(format='engine', imgsz=640) # 导出为TensorRT引擎,用于NVIDIA GPU极致加速

    导出ONNX是最通用和推荐的第一步,它可以在OpenCV DNN、ONNX Runtime等多种推理引擎上运行。

  2. 简化推理脚本:下面是一个使用ONNX Runtime进行推理的极简示例。

    import cv2 import numpy as np import onnxruntime as ort class TongueDetector: def __init__(self, onnx_path, conf_thres=0.5, iou_thres=0.5): self.session = ort.InferenceSession(onnx_path) self.input_name = self.session.get_inputs()[0].name self.conf_thres = conf_thres self.iou_thres = iou_thres # 假设模型输入是640x640 self.input_size = (640, 640) def preprocess(self, image): # 将BGR图像转换为RGB,并缩放到模型输入尺寸 img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) img = cv2.resize(img, self.input_size) # 归一化并转换维度为 [1, 3, H, W] img = img.astype(np.float32) / 255.0 img = np.transpose(img, (2, 0, 1)) img = np.expand_dims(img, axis=0) return img def detect(self, image): input_tensor = self.preprocess(image) outputs = self.session.run(None, {self.input_name: input_tensor}) # outputs[0] 的shape通常是 [1, 8400, 5+nc] # 这里需要根据你导出的YOLOv8版本的具体输出格式进行解析 # 通常包含一个巨大的预测张量,需要经过置信度过滤和NMS处理 # 此处省略具体的后处理代码,它通常包括: # 1. 将输出变形为 [num_boxes, 5+nc] # 2. 根据置信度阈值 self.conf_thres 进行过滤 # 3. 使用非极大值抑制 (NMS) 根据 self.iou_thres 过滤重叠框 # 4. 将框的坐标从640x640空间映射回原始图像空间 # 伪代码如下: # predictions = self.parse_output(outputs[0]) # boxes, scores, class_ids = self.non_max_suppression(predictions) # return boxes, scores, class_ids return [] # 返回检测结果列表 # 使用示例 detector = TongueDetector('best.onnx') img = cv2.imread('test_tongue.jpg') results = detector.detect(img) # 绘制结果到原图...

    实操心得:在实际部署中,后处理(解析模型输出、NMS)的代码复杂度不低,且需要与训练时保持一致。建议直接参考Ultralytics YOLOv8官方仓库中的utils/ops.py文件,里面有经过充分测试的non_max_suppression等函数,可以复制到你的项目中使用,避免重复造轮子和引入错误。

  3. 集成到应用:将上面的TongueDetector类封装成一个服务或模块。对于Web应用,可以使用FastAPI构建一个REST API;对于桌面应用,可以直接在GUI线程中调用;对于移动端,TFLite格式是更好的选择,可以集成到Android(Java/Kotlin)或iOS(Swift)项目中。

5. 常见问题与排查指南

在实际操作中,你几乎一定会遇到下面这些问题。这里我整理了从数据准备到模型部署全链条的常见“坑”和解决方法。

问题阶段具体现象可能原因排查与解决方案
数据准备训练时提示“Label file is empty”或“No labels found”。1. 图片和标签文件不匹配(如扩展名、文件名不一致)。
2. YOLO格式的标签文件.txt为空或格式错误(如坐标值大于1)。
3.tongue.yaml中的path路径设置错误,或train/val路径不存在。
1. 使用脚本检查每个图片是否都有对应的标签文件,且文件名(不含扩展名)严格一致。
2. 打开一个标签文件,检查格式是否为class_id x_center y_center width height,且数值在0-1之间。
3. 使用os.path.exists()逐级检查tongue.yaml中配置的路径是否存在。绝对路径比相对路径更可靠
模型训练Loss(损失)值为NaN或突然变得巨大。1.学习率(lr0)设置过高,这是最常见原因。
2. 数据中存在损坏的图片或标签。
3. 数据增强过于激进(如过度的色彩抖动)。
1.立即停止训练。将lr0降低一个数量级(如从0.01降到0.001)重新开始。
2. 检查数据加载环节,可以写一个简单的脚本遍历所有图片用cv2.imread()打开,看是否会报错。
3. 暂时关闭数据增强(augment=False),看问题是否消失,然后逐步添加增强项。
模型训练验证集mAP一直很低,或某个类别(如“瘀斑”)的AP为0。1.类别严重不平衡,少数类别样本不足。
2. 该类别(小目标)在图片中占比太小,模型难以学习。
3. 标签标注错误或质量差。
1. 使用过采样(复制少数类别样本)或为不同类别在损失函数中设置不同权重。
2. 尝试增大输入图像尺寸imgsz),如从640提高到832。或者在模型结构上引入更关注小目标的检测头。
3.可视化验证集的标注,使用YOLOv8提供的utils.plotting工具绘制标注框,肉眼检查“瘀斑”等难类别的标注是否准确、完整。
模型评估训练集精度很高,但验证集精度很低(过拟合)。1. 数据集太小,模型记住了训练样本的噪声。
2. 数据增强不够或模型过于复杂。
1.增加数据增强的强度和多样性。YOLOv8的augment=True已包含很多增强,可以尝试自定义更复杂的增强管道。
2. 尝试简化模型(换用更小的如yolov8n),或添加正则化手段,如增加weight_decay,或在模型中添加Dropout层。
3. 如果条件允许,收集更多数据是根本解决方法。
模型推理导出的ONNX/TFLite模型推理速度慢。1. 模型过大(如使用了yolov8x)。
2. 推理框架或环境未优化。
3. 后处理(NMS)代码效率低。
1. 权衡精度与速度,换用更小的模型(yolov8n,yolov8s)。
2. 对于ONNX,使用onnxruntime的GPU版本(onnxruntime-gpu)并确保CUDA可用。对于TFLite,启用GPU/NNAPI委托。
3.优化后处理:确保NMS操作使用向量化实现(如NumPy),避免Python循环。考虑将NMS也集成到ONNX模型中(YOLOv8导出时有一个nms选项)。
模型推理部署到新环境(如另一台电脑、手机)后检测结果错乱或无结果。1.预处理/后处理不一致:训练时和部署时的图像归一化方式(如除以255)、颜色通道顺序(BGR vs RGB)不匹配。
2. 动态尺寸问题:训练时固定为640,但推理时输入了任意尺寸图片。
1.严格统一预处理:将训练时dataset.py中的预处理逻辑(包括归一化均值标准差)完全复制到部署代码中。
2. 在推理前,将输入图像严格缩放到与训练相同的尺寸(如640x640),并保持长宽比进行填充(padding)以避免变形,同时需要记录填充信息以将预测框映射回原图。

最后再分享一个我踩过的坑:在早期尝试部署时,我忽略了图像填充(padding)对预测框坐标的影响。当输入图片不是正方形时,直接cv2.resize会导致舌头变形。正确的做法是保持长宽比进行缩放,然后在短边两侧进行填充,使其成为正方形。同时,必须记录填充的像素数,在得到模型输出的预测框后,需要先减去填充部分,再按缩放比例映射回原始图像坐标。这个细节没处理好,会导致部署后的检测框全部错位。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询