基于CNN的中草药识别系统设计与实现
1. 项目概述:基于CNN的中草药识别系统
这个毕业设计项目实现了一个基于卷积神经网络(CNN)的常见中草药识别系统。作为一名长期从事计算机视觉和深度学习开发的工程师,我认为这个选题非常具有实用价值。中草药识别一直是中医药领域的重要课题,传统的人工识别方法依赖专家经验,效率较低且容易出错。而基于深度学习的自动识别系统可以快速准确地完成这项任务。
系统采用B/S架构,前端使用Vue.js框架,后端采用Spring Boot框架,数据库使用MySQL,整体基于MVC设计模式开发。核心的CNN模型使用Python实现,通过TensorFlow/Keras框架构建和训练。系统能够识别数十种常见中草药,准确率可达90%以上,为中医药学生、从业者提供了一个便捷的识别工具。
2. 系统架构设计
2.1 技术栈选型
在技术选型方面,我们经过多方考量选择了以下技术组合:
前端技术:
- Vue.js 3.x:轻量级渐进式框架,组件化开发
- Element Plus:UI组件库,提供丰富的界面元素
- Axios:处理HTTP请求
- ECharts:数据可视化展示
后端技术:
- Spring Boot 2.7:简化配置,快速开发
- MyBatis-Plus:增强型ORM框架
- Shiro:安全认证框架
- Redis:缓存提高性能
深度学习部分:
- Python 3.8
- TensorFlow 2.x/Keras
- OpenCV:图像预处理
- Pillow:图像处理
数据库:
- MySQL 8.0:关系型数据库
- MinIO:对象存储,保存图片数据
技术选型考虑:这套技术栈组合成熟稳定,社区支持良好,各组件间集成度高,能够满足系统在性能、安全性和可维护性方面的需求。
2.2 系统架构设计
系统采用典型的三层架构:
┌───────────────────────────────────────┐
│ 客户端层 │
│ ┌───────────┐ ┌─────────────┐ │
│ │ Web浏览器 │ │ 移动端(未来) │ │
│ └───────────┘ └─────────────┘ │
└───────────────────────────────────────┘
▲
│ HTTP/HTTPS
▼
┌───────────────────────────────────────┐
│ 服务端层 │
│ ┌───────────┐ ┌─────────────┐ │
│ │ Spring Boot │ │ Python服务 │ │
│ └───────────┘ └─────────────┘ │
└───────────────────────────────────────┘
▲
│ JDBC/REST
▼
┌───────────────────────────────────────┐
│ 数据层 │
│ ┌───────────┐ ┌─────────────┐ │
│ │ MySQL │ │ MinIO │ │
│ └───────────┘ └─────────────┘ │
└───────────────────────────────────────┘
这种分层架构实现了关注点分离,各层职责明确,便于团队协作开发和后期维护。
3. CNN模型设计与实现
3.1 数据集准备
中草药识别系统的核心在于CNN模型的质量,而模型质量很大程度上取决于训练数据的质量。我们收集了15类常见中草药的高清图片,每类约500-800张,总计约10,000张图片。数据来源包括:
- 公开的中草药图像数据集
- 实地拍摄的中草药照片
- 专业书籍扫描图
- 网络公开图片(经过筛选)
数据预处理流程:
def preprocess_image(image_path, target_size=(224, 224)):
# 读取图像
img = cv2.imread(image_path)
# 转换为RGB格式
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 调整大小
img = cv2.resize(img, target_size)
# 归一化
img = img.astype('float32') / 255.0
# 数据增强:随机旋转、翻转等
if np.random.rand() > 0.5:
img = cv2.flip(img, 1)
if np.random.rand() > 0.5:
angle = np.random.randint(-15, 15)
img = rotate_image(img, angle)
return img
3.2 CNN模型架构
我们设计了一个基于ResNet50的改进模型,结构如下:
Input Layer (224x224x3)
│
├── ResNet50 Base (预训练权重)
│
├── Global Average Pooling
│
├── Dense (512 units, ReLU)
│
├── Dropout (0.5)
│
└── Output Layer (15 units, Softmax)
模型构建代码:
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout
from tensorflow.keras.models import Model
def build_model(num_classes=15):
# 加载预训练的ResNet50模型,不包括顶层
base_model = ResNet50(weights='imagenet', include_top=False,
input_shape=(224, 224, 3))
# 冻结预训练层的权重
for layer in base_model.layers:
layer.trainable = False
# 添加自定义顶层
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
predictions = Dense(num_classes, activation='softmax')(x)
# 构建完整模型
model = Model(inputs=base_model.input, outputs=predictions)
return model
3.3 模型训练与优化
训练策略:
- 使用迁移学习,先冻结ResNet50基础层
- 初始学习率0.001,使用ReduceLROnPlateau动态调整
- 批大小32,训练50个epoch
- 使用早停(EarlyStopping)防止过拟合
训练代码:
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
def train_model(model, train_generator, val_generator, epochs=50):
# 编译模型
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 回调函数
callbacks = [
ModelCheckpoint('best_model.h5', save_best_only=True),
EarlyStopping(patience=5, restore_best_weights=True),
ReduceLROnPlateau(factor=0.1, patience=3)
]
# 训练模型
history = model.fit(
train_generator,
steps_per_epoch=len(train_generator),
epochs=epochs,
validation_data=val_generator,
validation_steps=len(val_generator),
callbacks=callbacks
)
return history
经过训练,模型在测试集上达到了92.3%的准确率,混淆矩阵显示各类别的识别效果较为均衡。
4. 系统功能实现
4.1 用户管理模块
用户管理采用RBAC(基于角色的访问控制)模型,主要功能包括:
- 用户注册/登录
- 个人信息管理
- 角色权限分配
- 密码重置
核心数据库表设计:
CREATE TABLE `sys_user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码',
`real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`status` tinyint DEFAULT '1' COMMENT '状态 0:禁用 1:正常',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';
CREATE TABLE `sys_role` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '角色名称',
`code` varchar(50) NOT NULL COMMENT '角色编码',
`remark` varchar(100) DEFAULT NULL COMMENT '备注',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';
4.2 中草药识别模块
识别模块的核心流程:
- 用户上传中草药图片
- 系统对图片进行预处理
- 调用CNN模型进行预测
- 返回识别结果及置信度
- 保存识别记录
关键接口实现:
@RestController
@RequestMapping("/api/herb")
public class HerbRecognitionController {
@Autowired
private HerbRecognitionService recognitionService;
@PostMapping("/recognize")
public Result recognize(@RequestParam("file") MultipartFile file,
HttpServletRequest request) {
try {
// 验证文件
if (file.isEmpty()) {
return Result.error("请选择要上传的图片");
}
// 获取当前用户
Long userId = JwtUtil.getUserId(request);
// 调用识别服务
HerbRecognitionResult result = recognitionService.recognize(file, userId);
return Result.success(result);
} catch (Exception e) {
log.error("识别失败", e);
return Result.error("识别失败: " + e.getMessage());
}
}
}
4.3 数据统计模块
系统提供丰富的统计功能,帮助用户分析识别记录:
- 按时间统计识别次数
- 按中草药类型统计识别结果
- 用户活跃度分析
- 识别准确率分析
统计功能使用ECharts实现可视化展示,后端采用Redis缓存热点数据提高性能。
5. 系统部署与测试
5.1 部署方案
系统采用Docker容器化部署,主要组件包括:
- Nginx:前端静态资源和反向代理
- Spring Boot应用:业务逻辑处理
- Python服务:模型推理
- MySQL:数据存储
- Redis:缓存和会话管理
- MinIO:图片存储
使用docker-compose编排服务:
version: '3.8'
services:
nginx:
image: nginx:1.21
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./frontend/dist:/usr/share/nginx/html
depends_on:
- backend
- python-service
backend:
build: ./backend
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- DB_URL=jdbc:mysql://mysql:3306/herb_db
- DB_USER=root
- DB_PASSWORD=123456
depends_on:
- mysql
- redis
python-service:
build: ./python-service
ports:
- "5000:5000"
volumes:
- ./models:/app/models
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=herb_db
volumes:
- ./mysql-data:/var/lib/mysql
redis:
image: redis:6.2
ports:
- "6379:6379"
minio:
image: minio/minio
ports:
- "9000:9000"
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=minioadmin
volumes:
- ./minio-data:/data
command: server /data
5.2 性能测试
使用JMeter对系统进行压力测试,主要测试指标:
- 并发用户数:100-500
- 响应时间:<1s(图片识别接口)
- 吞吐量:>50 req/s
- 错误率:<1%
测试结果显示系统在200并发用户下表现稳定,平均响应时间800ms,吞吐量65 req/s,满足设计要求。
5.3 功能测试用例
中草药识别功能测试用例:
| 测试项 | 测试步骤 | 预期结果 | 实际结果 | 状态 |
|---|---|---|---|---|
| 正常识别 | 上传清晰的中草药图片 | 返回正确的识别结果及置信度 | 符合预期 | 通过 |
| 模糊图片 | 上传模糊的中草药图片 | 返回识别结果,置信度较低 | 符合预期 | 通过 |
| 非中草药图片 | 上传动物/风景图片 | 提示"非中草药图片" | 符合预期 | 通过 |
| 多物体图片 | 上传包含多种中草药的图片 | 返回主要物体的识别结果 | 符合预期 | 通过 |
| 大文件上传 | 上传10MB以上的图片 | 提示"图片大小超过限制" | 符合预期 | 通过 |
6. 项目总结与改进方向
经过三个月的开发,我们完成了这个基于CNN的中草药识别系统。系统实现了预期功能,识别准确率达到了92%以上,界面友好,操作简便。在开发过程中,我们积累了宝贵的深度学习模型优化和系统集成经验。
主要技术收获:
- 掌握了使用预训练CNN模型进行迁移学习的技巧
- 深入理解了图像分类任务中的数据增强方法
- 实践了Spring Boot与Python服务的集成方案
- 优化了深度学习模型在生产环境中的部署方案
改进方向:
- 扩充中草药种类,提高模型泛化能力
- 增加多角度识别功能,提升用户体验
- 开发移动端应用,支持拍照识别
- 引入目标检测技术,实现图片中多个中草药的识别
- 优化模型压缩技术,提高推理速度
这个项目不仅是一个毕业设计,更是一个有实际应用价值的系统。随着数据量的增加和模型的持续优化,系统的识别能力将不断提升,有望成为中医药领域的一个实用工具。
更多推荐



所有评论(0)