资讯动态

基于Python CNN的舌诊系统源码解析:从模型加载到食疗输出全流程

发布时间:2026/9/26 1:40:50 来源:尧图企业网站定制
简介这份资源是一套基于Python与CNN卷积神经网络实现的舌诊系统完整源码面向计算机相关专业的在校学生、高校教师及需要完成课程设计或毕业设计的开发者。项目通过深度学习模型对舌头图像进行症状识别并依据诊断结果给出相应食疗方案属于难度适中、易于上手的实战型项目。压缩包共包含26个文件以11个py源码文件为核心辅以3个keras模型文件、5个pyc编译文件、3个xml配置及json、md等说明文档整体约225.85MB。源码按功能划分为网络模型、检测器、工具函数与数据集等模块涵盖舌体检测、齿痕检测、颜色检测等关键环节并附带训练好的模型文件便于直接运行与二次开发。目前已有95人学习关注。对于希望深入理解CNN图像分类、积累完整项目经验或直接用于毕设课设的读者可借此掌握从数据处理、模型调用到症状诊断与食疗推荐的全流程实现思路。1. 舌诊 CNN 系统拆包一份能跑通的课程设计长什么样很多做深度学习课程设计的人卡在同一个地方模型代码网上抄一份数据集找不到前端界面不会写最后交上去的东西连自己都说不清输入输出是什么。这份「基于 Python 神经网络 CNN 实现的舌诊系统源码」正好踩在这个痛点上——它把卷积神经网络、舌象图像分类、症状映射和食疗方案输出串成了一条完整链路还附带了训练好的模型文件拿到手不用从零训起就能看到推理结果。它适合三类人正在做深度学习课程设计、需要一份结构完整可讲清楚的项目参考的在校生想用 Python 把 CNN 从理论落到一个具体分类任务上的入门者以及需要快速搭一个「图像输入 → 分类输出 → 业务建议」原型的技术验证人员。核心逻辑不复杂舌象图片经过预处理送进 CNN网络输出舌质、舌苔等类别再根据类别组合去匹配对应的症状描述和食疗建议。下面按「资源是什么 → 怎么跑起来 → 坑在哪 → 怎么改」的顺序拆开讲。2. 环境搭建与模型加载把推理链路先跑通在动任何代码之前先把运行环境搭对。这份源码是 Python 写的依赖 TensorFlow 或 Keras 做 CNN 推理图像处理靠 OpenCV 或 PIL界面部分常见做法是 PyQt 或 Flask。版本不匹配是新手翻车最多的地方尤其是 TensorFlow 2.x 和 1.x 的 API 差异直接决定模型能不能加载。2.1 Python 环境与依赖安装我一般会先建一个独立虚拟环境避免和系统里其他包的版本打架。假设你装的是 Python 3.8 到 3.10 之间的版本这个区间对 TensorFlow 2.x 兼容性最好操作如下# 创建虚拟环境名字叫 tongue_env python -m venv tongue_env # 激活环境Windows 用下面这行 tongue_env\Scripts\activate # macOS / Linux 用这行 source tongue_env/bin/activate # 安装核心依赖版本按源码 requirements 来没有就按这个装 pip install tensorflow2.10.0 pip install opencv-python4.8.0.74 pip install numpy1.24.3 pip install pillow10.0.0 pip install PyQt55.15.9这里几个参数值得说清楚。TensorFlow 选 2.10 是因为它在 Windows 原生支持上比较稳再往上到 2.11 之后 Windows 直接 pip 安装会变麻烦。numpy 锁 1.24 是因为 1.25 之后有些旧代码里的np.float别名被移除了源码里如果用了会直接报 AttributeError。opencv-python 负责图像读取和尺寸变换舌象图片预处理基本靠它。PyQt5 是界面框架如果源码用的是 Flask 网页版那这行换成pip install flask即可。装完之后验证一下import tensorflow as tf import cv2 import numpy as np print(TF:, tf.__version__) print(CV2:, cv2.__version__) print(NP:, np.__version__)三行都打印出版本号说明环境没问题。如果 TensorFlow 导入报 DLL 错误八成是缺 Visual C Redistributable去微软官网装一个最新的 x64 版本就行这是 Windows 上的血泪经验。2.2 模型文件加载与输入格式确认源码包里通常会有一个.h5或.keras后缀的模型文件这是训练好的权重。加载方式取决于保存格式from tensorflow.keras.models import load_model # 加载模型compileFalse 表示不重新编译优化器纯推理够用 model load_model(tongue_model.h5, compileFalse) # 打印模型结构确认输入输出维度 model.summary()compileFalse这个参数很关键。如果模型保存时带了自定义损失函数或自定义层不加这个参数加载会报「Unknown loss function」之类的错。纯做推理不需要优化器和损失函数关掉最省事。model.summary()会打印出每一层的名称、输出形状和参数量。你要重点关注第一层的 input_shape 和最后一层的输出类别数。常见的舌诊 CNN 输入是(224, 224, 3)或(128, 128, 3)输出类别数对应舌质或舌苔的分类数量比如 5 类、8 类都有可能。这个数字决定了后面标签映射表要写几项。推理前图像必须做和训练时一致的预处理这是最容易忽略的坑import cv2 import numpy as np def preprocess_image(img_path, target_size(224, 224)): # 读取图片 img cv2.imread(img_path) # BGR 转 RGBOpenCV 默认读进来是 BGR img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 缩放到模型要求的尺寸 img cv2.resize(img, target_size) # 归一化到 0-1和训练时保持一致 img img.astype(float32) / 255.0 # 增加 batch 维度变成 (1, 224, 224, 3) img np.expand_dims(img, axis0) return img img_tensor preprocess_image(test_tongue.jpg) prediction model.predict(img_tensor) print(各类别概率:, prediction) print(预测类别索引:, np.argmax(prediction))这段代码里每一步都有讲究。BGR 转 RGB 是因为 OpenCV 的默认通道顺序和训练时用的 PIL 或 tf.keras 预处理不一致不转的话颜色通道错位预测结果会离谱。归一化方式必须和训练时完全一样训练用了/255.0推理也得用训练用了(x-mean)/std推理也得照做否则输入分布偏移模型等于瞎猜。np.expand_dims加 batch 维度是因为model.predict要求输入是四维张量少这一维直接报形状错误。3. 舌象分类到食疗输出业务映射层怎么接模型只负责输出一个类别索引比如「3」或「5」但用户要看到的是「舌苔厚腻」和「建议食用薏米山药粥」。中间这层映射逻辑是这份源码区别于纯 demo 的地方也是课程设计答辩时最能讲出东西的部分。3.1 标签映射表与症状描述结构模型输出的数字本身没有意义需要一张映射表把它翻译成可读的舌象特征。常见做法是用一个字典或 JSON 文件来维护# 标签映射表索引要和训练时的类别顺序一致 label_map { 0: {name: 淡红舌薄白苔, desc: 舌色淡红舌苔薄白属正常舌象}, 1: {name: 红舌黄苔, desc: 舌色偏红苔黄多提示体内有热}, 2: {name: 淡白舌, desc: 舌色淡白多见于气血不足}, 3: {name: 厚腻苔, desc: 舌苔厚腻多与湿浊内蕴相关}, 4: {name: 裂纹舌, desc: 舌面有裂纹常见于阴虚或津液不足} } # 推理后取最大概率对应的标签 pred_idx int(np.argmax(prediction)) result label_map.get(pred_idx, {name: 未知, desc: 无法识别}) print(f识别结果{result[name]}) print(f症状描述{result[desc]})这张表的索引顺序必须和训练时class_indices的顺序完全一致。Keras 的ImageDataGenerator或flow_from_directory是按文件夹名称字母序生成类别索引的如果你训练时文件夹叫0_normal、1_red、2_pale那索引就是按这个顺序来的。搞错顺序是「模型准确率很高但预测结果全错」的经典原因排查时先对这张表。3.2 食疗方案匹配与输出组装症状到食疗的映射通常是一对多的关系一个舌象特征可能对应多条建议。源码里一般用嵌套字典或单独的 JSON 来存# 食疗方案库key 对应 label_map 的索引 diet_plan { 0: [饮食均衡无需特殊调理, 保持规律作息], 1: [绿豆汤清热, 莲子心泡水, 避免辛辣油腻], 2: [红枣桂圆粥补气血, 山药炖排骨, 适量摄入红肉], 3: [薏米红豆汤祛湿, 冬瓜汤利水, 少吃甜腻食物], 4: [银耳百合羹滋阴, 石斛泡水, 多喝水少熬夜] } # 组装最终输出 def build_result(pred_idx): info label_map.get(pred_idx, {}) plans diet_plan.get(pred_idx, []) return { 舌象: info.get(name, 未知), 症状: info.get(desc, ), 食疗建议: plans } final build_result(pred_idx) for k, v in final.items(): print(f{k}: {v})这段逻辑本身不复杂但有两个工程上的注意点。一是食疗方案的内容要标注「仅供参考不构成医疗建议」课程设计里加上这句话既合规也显得严谨。二是如果源码用的是 Flask 做 Web 界面这部分输出要转成 JSON 返回给前端如果是 PyQt就绑定到界面上的文本框控件。不管哪种核心都是「索引 → 查表 → 组装」三步。3.3 批量测试与准确率验证单张图片跑通之后建议用一批测试图验证整体表现。源码包里如果有测试集直接遍历计算准确率import os test_dir test_images correct 0 total 0 for fname in os.listdir(test_dir): if not fname.lower().endswith((.jpg, .png, .jpeg)): continue # 假设文件名格式为 类别索引_任意名.jpg方便取真实标签 true_label int(fname.split(_)[0]) img_tensor preprocess_image(os.path.join(test_dir, fname)) pred model.predict(img_tensor, verbose0) pred_label int(np.argmax(pred)) total 1 if pred_label true_label: correct 1 print(f测试样本数{total}) print(f准确率{correct / total:.2%} if total 0 else 无有效测试图片)verbose0是关掉predict的进度条输出批量跑的时候屏幕干净很多。文件名带真实标签是一种常见的测试集组织方式如果你的测试图没有这个命名规则就手动维护一个(文件路径, 真实标签)的列表来遍历。准确率明显低于训练时报告的验证集准确率通常意味着预处理不一致或标签映射顺序错了回到 3.1 节对一遍。4. 避坑与排查跑不起来时先看这几条这份源码在实际运行中遇到的问题八成集中在下面五个地方。每条按「现象 → 原因 → 解决」写对着排查基本能覆盖大部分翻车场景。现象一加载模型时报「Unknown layer」或「Unknown loss function」。原因是模型保存时用了自定义层或自定义损失函数加载时没有提供对应的定义。解决办法是在load_model里加compileFalse如果还报错就需要找到源码里自定义层的类定义通过custom_objects参数传进去比如load_model(model.h5, custom_objects{MyLayer: MyLayer})。现象二预测结果永远是同一个类别。原因通常是预处理不一致最常见的是归一化方式不对或颜色通道没转。训练时如果用了rescale1./255推理也必须除 255训练时如果用的是 RGB推理时 OpenCV 读进来是 BGR 就必须转。另一个可能是输入尺寸不对模型要 224×224 你传了 128×128卷出来的特征全乱。排查方法是打印输入张量的形状和数值范围和训练时的生成器输出对比。现象三TensorFlow 导入报 DLL load failed。这是 Windows 上的经典问题原因是缺少 Microsoft Visual C Redistributable。去微软官网下载最新的 x64 版本装上重启终端再试。如果还不行检查 Python 版本是不是 3.11 以上TensorFlow 2.10 不支持 3.11降到 3.10 或 3.9。现象四界面能打开但点击识别没反应。如果源码是 PyQt 写的大概率是信号槽没连上或者图片路径没取到。在按钮的槽函数第一行加print(按钮被点击了)确认事件有没有触发。如果触发了但没结果检查model对象是不是在界面初始化时就加载好了有些写法把加载放在按钮回调里每次点击都重新加载模型慢到以为卡死。现象五食疗方案输出为空或报 KeyError。原因是预测出的类别索引在diet_plan字典里没有对应的键。这通常发生在模型输出类别数和映射表条目数不一致的时候比如模型输出 6 类但映射表只写了 5 项。解决办法是用diet_plan.get(pred_idx, [暂无建议])做兜底同时打印pred_idx确认模型实际输出的类别范围。注意如果源码里的模型文件后缀是.h5但加载时报格式错误先确认文件有没有在传输过程中损坏用h5py打开看看能不能读到结构。文件损坏的话只能重新找原始模型。5. 改造与进阶把课程设计变成能讲清楚的项目跑通只是第一步课程设计答辩时老师一定会问「你自己做了什么」。与其支支吾吾说「网上找的」不如在原有基础上做两三个小改造既加深理解又有的讲。5.1 数据增强与模型微调如果源码里带了训练脚本可以试着在ImageDataGenerator里加几个增强参数观察准确率变化from tensorflow.keras.preprocessing.image import ImageDataGenerator train_datagen ImageDataGenerator( rescale1./255, # 归一化 rotation_range15, # 随机旋转 ±15 度 width_shift_range0.1, # 水平平移 10% height_shift_range0.1, # 垂直平移 10% horizontal_flipTrue, # 水平翻转 zoom_range0.1, # 缩放 10% validation_split0.2 # 20% 做验证 )rotation_range对舌象图片特别有用因为拍照时舌头角度不可能完全正对。horizontal_flip要慎用舌象左右翻转在医学上可能改变含义如果类别对左右敏感就关掉。zoom_range模拟远近不同的拍摄距离。加完增强后重新训练如果验证集准确率比不加时高说明模型泛化能力确实提升了这就是答辩时能讲的一个点。5.2 用混淆矩阵定位弱类别准确率只有一个数字看不出模型在哪些类别上容易错。加一段混淆矩阵代码能直观看到哪两类容易混from sklearn.metrics import confusion_matrix, classification_report import seaborn as sns import matplotlib.pyplot as plt # 假设 y_true 和 y_pred 是真实标签和预测标签的列表 cm confusion_matrix(y_true, y_pred) print(classification_report(y_true, y_pred)) plt.figure(figsize(8, 6)) sns.heatmap(cm, annotTrue, fmtd, cmapBlues) plt.xlabel(预测类别) plt.ylabel(真实类别) plt.title(舌象分类混淆矩阵) plt.show()classification_report会输出每个类别的精确率、召回率和 F1 分数。如果某个类别的召回率特别低说明模型把很多该类样本错分到了别的类这时候可以针对性地补充该类训练数据或者在损失函数里给该类加权重。这个分析过程写在课程设计报告里比单纯报一个准确率有说服力得多。5.3 从单张推理到批量导出最后一个小技巧把推理结果批量导出成 CSV方便后续分析或展示import pandas as pd results [] for fname in os.listdir(test_dir): if not fname.lower().endswith((.jpg, .png)): continue img_tensor preprocess_image(os.path.join(test_dir, fname)) pred model.predict(img_tensor, verbose0) idx int(np.argmax(pred)) results.append({ 文件名: fname, 预测舌象: label_map.get(idx, {}).get(name, 未知), 置信度: float(np.max(pred)), 食疗建议: .join(diet_plan.get(idx, [])) }) df pd.DataFrame(results) df.to_csv(舌诊推理结果.csv, indexFalse, encodingutf-8-sig) print(f已导出 {len(df)} 条结果)encodingutf-8-sig是为了 Excel 打开 CSV 时中文不乱码不加这个参数用 Excel 打开会看到一堆问号。置信度那一列可以帮你判断哪些样本模型拿不准低于 0.6 的可以单独挑出来人工复核。从那以后我每次拿到一个带模型文件的课程设计都强制先跑一遍model.summary()和单张推理确认输入输出对得上再往下做界面。这个习惯帮我省掉了无数次「代码全对但结果全错」的排查时间。希望这份拆解能帮你把这份舌诊 CNN 源码真正跑起来、讲清楚、改出自己的东西。本文还有配套的精品资源点击获取

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

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

免费获取报价 →
↑