news 2026/10/2 2:55:27

基于Python+YOLO的舌象诊断系统:从数据标注到界面部署的毕业设计实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Python+YOLO的舌象诊断系统:从数据标注到界面部署的毕业设计实战

简介:这份资源面向计算机、人工智能及医学信息方向的本科生与研究生,提供一套可直接用于毕业设计、期末大作业或课程设计的舌象诊断系统完整方案。项目以Python为开发语言,结合YOLO深度学习目标检测算法,实现舌象图像的识别与分类诊断,代码附带详细注释,新手也能快速理解整体流程与关键实现。压缩包共183个文件,约42.7MB,包含54个py源码文件、61张jpg样本图片、40个pyc编译文件,以及txt说明、json配置、ui界面文件、ttf字体和docx学习路线文档等,覆盖数据、模型、界面与文档多个环节。目前已有223人学习下载。读者可获得完整可运行的工程代码、配套数据集、学习路线文档与部署说明,便于快速复现实验、理解YOLO在医学图像中的应用,并在此基础上完成功能扩展与论文撰写。

1. 舌象诊断系统:从一张舌头照片到可复现的毕业设计

很多做计算机毕业设计的同学,选题时都会遇到同一个尴尬:想蹭深度学习的热度,又不想做烂大街的人脸识别、猫狗分类。舌象诊断系统恰好卡在一个微妙的位置上——它属于中医智能化这个听起来有门槛的方向,但落到工程上,本质就是一个图像分类任务,用 Python 加 YOLO 系列模型就能跑通。我见过太多人卡在第一步:数据集从哪来、标注怎么做、YOLO 到底用来检测还是分类、训练完怎么接到一个能演示的界面上。这篇笔记就按我自己踩过的路子,把「基于 Python + YOLO 深度学习的舌象诊断系统」从数据准备、模型训练到推理部署整条链路拆开讲清楚。适合正在做毕业设计、需要一套能跑通、能答辩、能写进论文的完整方案的人,也适合想入门深度学习图像分类但缺一个真实项目的同学。核心词就三个:Python、YOLO、舌象诊断,后面每一章都围绕它们展开。

2. 舌象诊断到底在诊断什么:任务定义与数据准备

2.1 先想清楚是检测还是分类,别一上来就堆模型

舌象诊断在中医里看的是舌质和舌苔两大部分。舌质看颜色(淡白、红、绛、紫),舌苔看颜色和厚薄(白苔、黄苔、腻苔、剥落苔)。落到深度学习任务上,这里有个关键分叉:你是要做目标检测,还是做图像分类?

如果你只是判断「这张舌头照片属于哪一类舌象」,那就是分类任务,YOLO 的分类分支(YOLOv8-cls 这类)或者干脆用 ResNet、EfficientNet 都行。但如果你要定位舌头在整张脸照片里的位置,再判断舌体区域的颜色特征,那就需要检测。实际毕业设计里,我建议走「检测 + 分类」两阶段:先用 YOLO 检测把舌头框出来,裁出舌体区域,再用一个分类网络判断舌象类别。这样做的好处是答辩时逻辑清晰,工作量也够,不至于被老师问「你这不就是个分类吗」。

常见做法是直接用 YOLOv8 做检测,把舌体作为一个类别标注,然后对裁剪出的舌体区域做颜色特征分析或二级分类。如果你时间紧,也可以只做分类,但数据集必须已经是裁剪好的舌体图。

2.2 数据集从哪来:三条路和各自的坑

舌象数据集不像猫狗数据那样现成。我一般会走这三条路:

第一条,公开数据集。网上能搜到一些中医舌象数据集,比如部分高校实验室放出的舌象图库,数量从几百到几千张不等。这类数据集的问题是标注质量参差不齐,有的只标了类别没标位置,有的图片分辨率很低。用之前一定要自己过一遍,把模糊的、重复的、明显标错的剔掉。

第二条,自己采集。找同学当志愿者,用手机在自然光下拍舌头照片。这里有个血泪经验:光线对舌色影响极大,早上和晚上拍的同一根舌头能差出两个色号。所以采集时尽量固定光源,比如用环形补光灯,或者统一在窗边自然光下拍。每人拍 3 到 5 张,覆盖不同角度。

第三条,网络爬取加人工筛选。用 Python 爬虫从公开图片站抓舌象相关图片,然后人工清洗。这条路量大但噪声也大,适合做数据增强的补充。

不管哪条路,最终你需要的目录结构大概是这样:

dataset/ ├── images/ │ ├── train/ │ │ ├── 001.jpg │ │ └── ... │ └── val/ │ ├── 101.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── 001.txt │ │ └── ... │ └── val/ │ └── ... └── data.yaml

其中 labels 里的 txt 文件是 YOLO 格式的标注,每行是类别编号 中心x 中心y 宽 高,坐标都归一化到 0 到 1 之间。data.yaml 写清楚训练集和验证集路径、类别数和类别名。

2.3 标注工具和标注规范:别让标注毁掉整个项目

标注工具我用 LabelImg 或者 Roboflow 的在线标注。LabelImg 装起来简单,pip install labelImg然后命令行敲labelImg就能开。标注时只框舌体区域,不要把牙齿、嘴唇框进去。如果做分类,就按文件夹分好类,比如dataset/train/白苔/、dataset/train/黄苔/。

标注规范要提前定死:舌体边界怎么算、舌根部分被挡住算不算、多根舌头入镜怎么办。我一般要求标注框紧贴舌体边缘,舌根被牙齿挡住的部分不强行框。标注完随机抽 20 张检查一遍,这一步能省掉后面训练时一半的玄学问题。

提示:标注文件里的类别编号从 0 开始,别写成 1,YOLO 训练时会直接报索引越界。

3. 用 YOLOv8 训练舌体检测模型:环境、配置与训练命令

3.1 Python 环境与依赖安装:一次装对,别反复重装

环境这块,我强烈建议用 conda 建一个独立环境,别在 base 里瞎装。Python 版本选 3.9 或 3.10,太新的版本有些包还没跟上。命令如下:

conda create -n tongue python=3.10 conda activate tongue pip install ultralytics opencv-python numpy matplotlib pyyaml

ultralytics 这个包把 YOLOv8 的训练、验证、推理全包了,装它一个基本够用。opencv 用来做图像预处理和推理时的读取。如果你要用 GPU 训练,还得装对应版本的 PyTorch,去 PyTorch 官网按 CUDA 版本选命令,别直接pip install torch,那样装的是 CPU 版,训练慢到你想砸电脑。

装完验证一下:

import torch print(torch.__version__) print(torch.cuda.is_available())

如果第二行输出 False,说明 GPU 没配上,检查 CUDA 版本和驱动。CPU 也能训,但舌象数据集稍微大一点就得等好几个小时,毕业设计时间紧的话还是想办法用上 GPU,实验室机器或者云平台都行。

3.2 data.yaml 怎么写:五个字段一个都不能错

data.yaml 是 YOLO 训练的数据入口,写错了直接开不了工。标准写法:

path: /home/user/tongue_dataset train: images/train val: images/val nc: 1 names: ['tongue']

path 是数据集根目录,train 和 val 是相对路径。nc 是类别数,舌体检测就 1 类。names 是类别名列表,顺序要和标注里的编号对应。如果你做的是舌象分类而不是检测,那 data.yaml 里要写train: train这种指向分类文件夹的路径,具体看 ultralytics 文档里分类任务的写法。

有个容易翻车的点:path 用了相对路径时,训练命令必须在正确的工作目录下执行,否则 YOLO 找不到数据。我一般直接写绝对路径,省得来回 cd。

3.3 训练命令与关键参数:epochs、imgsz、batch 怎么定

训练命令一行搞定:

yolo detect train data=data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 name=tongue_detect

逐个说参数。model=yolov8n.pt 是用的预训练权重,n 是 nano 版,最小最快,适合毕业设计这种数据量不大的场景。如果你数据多、要求高,可以换 yolov8s.pt 或 yolov8m.pt,但训练时间翻倍。epochs=100 是训练轮数,舌象数据集一般 500 到 2000 张图的话,100 轮够收敛了,看验证集 loss 不再下降就可以停。imgsz=640 是输入图像尺寸,舌体检测 640 够用,太小会丢细节,太大显存吃不消。batch=16 是批大小,显存 8G 以下建议降到 8 或 4。

训练过程中终端会打印每一轮的 box_loss、cls_loss 和 mAP。重点看 mAP50 这个指标,它表示 IoU 阈值 0.5 时的平均精度,舌体检测一般能到 0.9 以上算正常。如果 mAP 一直上不去,先检查标注是不是有问题,再看学习率要不要调。

训练完的权重存在runs/detect/tongue_detect/weights/best.pt,这个文件后面推理和部署都要用。

3.4 训练结果怎么看:别只盯着 loss

训练结束后,runs 目录下会生成一堆图,其中results.png和confusion_matrix.png最值得看。results.png 里看 train loss 和 val loss 的走势,如果 train 一直降但 val 开始涨,说明过拟合了,得加数据增强或者减模型复杂度。confusion_matrix 看分类有没有系统性混淆,比如把白苔大量判成黄苔,那可能是光照没归一化好。

我一般还会跑一下验证命令:

yolo detect val model=runs/detect/tongue_detect/weights/best.pt data=data.yaml

它会输出每一类的 precision、recall 和 mAP。如果某一类 recall 特别低,说明这类样本太少,回去补数据。

4. 从检测框到舌象分类:裁剪、特征与二级模型

4.1 用检测结果裁剪舌体区域:坐标换算别搞反

检测模型输出的是归一化坐标,要还原到原图裁剪,得先乘回宽高。代码大概这样:

import cv2 from ultralytics import YOLO model = YOLO('runs/detect/tongue_detect/weights/best.pt') img = cv2.imread('test.jpg') results = model(img) for r in results: boxes = r.boxes for box in boxes: x1, y1, x2, y2 = box.xyxy[0].tolist() x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2) tongue = img[y1:y2, x1:x2] cv2.imwrite('tongue_crop.jpg', tongue)

这里 xyxy 返回的是左上角和右下角的绝对像素坐标,直接切片就行。注意 OpenCV 读图是 BGR 顺序,后面如果送进分类模型,记得转成 RGB。裁剪时稍微往外扩几个像素,避免把舌体边缘切掉。

4.2 舌象分类模型:小数据集用迁移学习最稳

裁剪出来的舌体图,按白苔、黄苔、腻苔等类别分好文件夹,就可以训分类模型了。数据量小的时候,别自己搭网络从零训,直接用预训练模型微调。ultralytics 也支持分类任务:

yolo classify train data=tongue_cls model=yolov8n-cls.pt epochs=80 imgsz=224

分类数据集的目录结构是每个类别一个文件夹:

tongue_cls/ ├── train/ │ ├── baitai/ │ ├── huangtai/ │ └── nita/ └── val/ ├── baitai/ ├── huangtai/ └── nita/

imgsz=224 是分类常用的输入尺寸,因为分类网络一般接受 224x224。epochs 设 80 左右,看验证准确率不再提升就停。如果类别不平衡,比如白苔样本远多于黄苔,可以在训练时加class_weights或者对少样本类做数据增强。

4.3 颜色特征辅助判断:传统方法在舌象里还有用

深度学习不是万能的。舌象里舌质颜色和舌苔颜色的区分,有时候用 HSV 色彩空间做阈值分割反而更直观。我一般会在分类模型之外,加一个颜色特征提取作为辅助:

import cv2 import numpy as np tongue = cv2.imread('tongue_crop.jpg') hsv = cv2.cvtColor(tongue, cv2.COLOR_BGR2HSV) h, s, v = cv2.split(hsv) # 计算色调直方图,判断偏红还是偏白 hist_h = cv2.calcHist([h], [0], None, [180], [0, 180]) dominant_hue = np.argmax(hist_h) print(f'主色调: {dominant_hue}')

色调值在 0 到 10 附近偏红,20 到 40 偏黄,100 以上偏紫。这个特征可以和分类模型的输出做加权融合,答辩时也能体现你做了多模态分析,不是单纯调包。

注意:HSV 阈值受光照影响大,采集数据时尽量统一光源,否则颜色特征会变成噪声。

5. 避坑与排查:舌象项目里最容易翻车的五件事

5.1 训练 loss 不降,mAP 一直是 0

现象:训练跑了几十轮,box_loss 和 cls_loss 都不怎么动,mAP 始终接近 0。

原因:九成是标注格式错了。YOLO 要求标注坐标归一化到 0 到 1,如果标注工具导出的是绝对像素坐标,或者类别编号从 1 开始,模型就学不到东西。

解决:打开一个标注 txt 文件,检查每行是不是五个值,后四个是不是都在 0 到 1 之间。类别编号从 0 开始。确认无误后重新训练。

5.2 验证集准确率很高,但自己拍的照片一测就错

现象:验证集 mAP 0.95,拿手机拍张舌头照片推理,框都框不准。

原因:数据分布不一致。训练集可能是实验室环境下拍的,光照、角度、背景都和你手机拍的不一样。模型过拟合到了训练集的特定风格。

解决:在训练时加数据增强,比如随机亮度、对比度、旋转、裁剪。ultralytics 默认开了部分增强,可以在训练命令里加augment=True并调hsv_h、hsv_s、hsv_v参数。另外自己采集一批手机拍的照片加入训练集,哪怕只有几十张,也能明显改善。

5.3 显存爆了,batch 降到 1 还是 OOM

现象:训练一开始就报 CUDA out of memory,batch 调到 1 也不行。

原因:imgsz 设太大了,或者模型选大了。640 的输入配 yolov8m 在 8G 显存上就可能爆。

解决:先把 imgsz 降到 416 或 320,模型换成 yolov8n。如果还不行,检查是不是有其他进程占着显存,nvidia-smi看一下,把没用的进程 kill 掉。

5.4 推理时检测框位置对,但分类结果全是同一类

现象:YOLO 检测没问题,但二级分类模型对所有输入都输出同一个类别。

原因:分类数据集类别不平衡太严重,或者验证集和训练集有重叠导致过拟合。也有可能是图像预处理时忘了归一化,输入数值范围不对。

解决:检查每个类别的样本数,少样本类做增强或过采样。确认训练和验证文件夹没有重复图片。分类模型输入前要做和训练时一致的归一化,ultralytics 内部会处理,但如果你自己写推理代码,记得除以 255。

5.5 答辩时被问「你这和中医有什么关系」

现象:技术跑通了,但老师觉得你只是做了个图像分类,没有中医理论支撑。

原因:缺少医学解释层。舌象诊断系统不能只输出「黄苔」,还要说明黄苔在中医里对应什么证型。

解决:在系统输出里加一个映射表,把舌象类别映射到常见中医证型,比如黄腻苔对应湿热,白苔对应寒证。这个映射不需要你自己编,查中医诊断学教材就有。答辩时把这条链路讲清楚:图像到舌象类别,舌象类别到证型参考,证型到调理建议。这样技术工作和中医语境就接上了。

6. 把模型接到界面上:一个能演示的最小系统

毕业设计最后总要有个能点、能看的界面。我一般用 Gradio 或者 Streamlit,几行代码就能搭一个网页 demo,比 PyQt 省事得多。以 Gradio 为例:

import gradio as gr import cv2 from ultralytics import YOLO det_model = YOLO('runs/detect/tongue_detect/weights/best.pt') cls_model = YOLO('runs/classify/tongue_cls/weights/best.pt') def diagnose(image): results = det_model(image) for r in results: for box in r.boxes: x1, y1, x2, y2 = map(int, box.xyxy[0].tolist()) tongue = image[y1:y2, x1:x2] cls_result = cls_model(tongue) probs = cls_result[0].probs top1 = probs.top1 names = cls_result[0].names return f"舌象类别: {names[top1]}, 置信度: {probs.top1conf:.2f}" return "未检测到舌体" demo = gr.Interface(fn=diagnose, inputs=gr.Image(), outputs=gr.Text()) demo.launch()

这段代码把检测和分类串起来,输入一张图,输出舌象类别和置信度。Gradio 会自动生成网页界面,支持拖拽上传和摄像头拍照。部署到服务器上加个share=True就能生成临时公网链接,答辩时直接演示。

参数上,probs.top1是最高置信度的类别索引,top1conf是对应置信度。如果置信度低于 0.6,我一般会在输出里加一句「建议重新拍摄」,避免给出不可靠结果。

这套系统跑通之后,你可以继续做的进阶方向有几个:一是加舌体分割,用 YOLOv8-seg 把舌体像素级抠出来,颜色分析会更准;二是做多标签分类,一根舌头可能同时有齿痕和厚苔;三是把中医证型映射做成知识图谱,让输出更有医学逻辑。我自己做这类项目最大的教训是:别一上来就追求模型多复杂,先把数据标注和训练流程跑通,哪怕用最小的 yolov8n,能稳定输出正确结果,比堆一堆花哨模块但跑不起来强得多。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 2:55:15

Java对接美团OpenAPI:HTTPS双向认证配置实战指南

对接美团开放平台的时候,Java后端服务调用OpenAPI最容易让人头大的环节就是HTTPS双向认证配置。业务代码写得再顺,联调环境一跑就被"PKIX path building failed"拍回来,证书、密钥库、SSLContext、连接池几个概念搅在一起&#xff…

作者头像 李华
网站建设 2026/10/2 2:54:53

DeepSeek论文AI率99%?拆解AI检测原理与深度改写全流程

看到"DeepSeek写的论文AI率99%"这个标题,我第一反应是:太熟悉了。上个月我帮一个研究生朋友看论文初稿,他凌晨两点发来检测截图,同屏并列着两份报告——左边是DeepSeek生成的综述初稿,AI率97.6%;…

作者头像 李华
网站建设 2026/10/2 2:54:53

xactengine2_2.dll丢失无法启动程序?DirectX运行库修复全攻略

前几天帮人处理电脑问题,对方说玩老游戏突然弹了个窗:无法启动此程序,因为计算机中丢失xactengine2_2.dll。截图我熟得很,这种直接点名dll文件丢失的报错,在Windows上太常见了。xactengine2_2.dll是微软DirectX音频组件…

作者头像 李华
网站建设 2026/10/2 2:54:49

Java全栈开发面试实战:从基础源码到微服务架构全面解析

最近团队做技术面复盘,我连续跟了几十场Java岗位的面试,有个现象特别明显:候选人分两种,一种能把八股文背得滚瓜烂熟,从Hashmap的负载因子到Spring Bean的生命周期倒背如流;另一种可能某个原理讲得没那么全…

作者头像 李华
网站建设 2026/10/2 2:54:09

Win11 21H2最终版ISO下载:体验接近Win10的22000.3260完整镜像

用了这么多年Windows,我越来越认同一个判断:一个系统版本走到生命周期终点时,往往是它最成熟、最值得被使用的时刻。Win11 21H2最终版22000.3260就是这么个东西——它是Win11自2021年发布以来,第一个正式版本分支的收官之作&#…

作者头像 李华
网站建设 2026/10/2 2:53:59

Epic、Feature、Story、Task四层责任切片解析

1. 别再把Epic当“大需求”——先搞懂这四个词在真实项目里到底谁管谁你有没有遇到过这样的场景:产品经理在站会上说“这个Epic下周要交付”,开发组长点头说“没问题,Story都拆完了”,测试同事却皱着眉问“Task里没写验收标准&…

作者头像 李华