基于Python的系膜预测系统

本文介绍了如何利用MobileNetV2模型进行虹膜预测,并结合PyQt5创建了一个用户界面,实现图像选择、预处理、模型预测和结果显示。详细步骤包括数据准备、模型构建、训练、评估以及如何将训练好的模型应用到GUI界面中进行实时识别。
摘要由CSDN通过智能技术生成

数据准备:需要自己找一张背景图(.png)、导入需要的系膜图片资源(这里我上传了)

1、建立虹膜预测MobileNetV2模型

1.1 设计思路

  1. 导入必要的库

  2. 使用TensorFlow和Keras库来构建、训练和评估模型。
  3. 导入MobileNetV2作为预训练模型,它在ImageNet数据集上进行了预训练,能够提取图像特征。
  4. 加载预训练模型 (In[5]):

    • 加载MobileNetV2模型,不包括顶层分类器,以便在此基础上添加自定义的分类层。
    • 创建Sequential模型,并添加全局平均池化层和两个全连接层,最后一个全连接层使用softmax激活函数来进行多类分类。
  5. 模型编译 (In[6]):

    • 冻结预训练模型的权重,这样在训练过程中,预训练模型的权重不会更新。
    • 使用Adam优化器编译模型,并添加权重衰减来减少过拟合。
  6. 数据准备 (In[7]):

    • 定义ImageDataGenerator来对图像进行预处理和增强。
    • 从原始数据目录中分离出训练集和验证集,确保每个类别的图像都被适当地分配。
  7. 创建数据生成器 (In[8] 和 In[9]):

    • 使用ImageDataGenerator创建训练和验证数据的生成器,这些生成器能够实时地对图像进行预处理并生成批次。
  8. 设置模型检查点 (In[21]):

    • 定义ModelCheckpoint回调,以便在每个epoch结束后,如果验证集准确度提升,则保存当前最佳模型。
  9. 模型训练 (In[22]):

    • 使用fit方法训练模型,指定训练轮数、训练集生成器、验证集生成器和回调函数。
  10. 加载和评估最佳模型 (In[23]):

    • 加载保存的最佳模型,并使用验证集评估其性能。
  11. 可视化预测结果 (In[14]):

    • 使用matplotlib库展示模型对验证集图像的预测结果,并将真实标签与预测标签进行对比。
  12. 保存模型 (In[24]):

    • 可选步骤,将训练好的模型保存为HDF5文件,以便后续使用或部署。
  13. 中文显示支持 (In[10]):

    • 设置matplotlib的参数以支持中文字符显示,避免在绘制图像时中文乱码。
  14. 获取类别标签顺序 (In[15]):

    • 加载训练数据集,并获取类别标签的顺序,这对于理解模型预测的类别很重要。

1.2  代码的实践

In[1]:

这部分是脚本的开始,导入了必要的库。

import tensorflow as tf
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, GlobalAveragePooling2D
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from keras import regularizers
  • tensorflow 和 tf.keras 是用于构建和训练深度学习模型的主要库。
  • MobileNetV2 是一个预训练的深度学习模型,用于图像分类任务。
  • Sequential 是Keras中用来构建模型的容器。
  • DenseDropout 和 GlobalAveragePooling2D 是Keras中的层类型,分别用于添加全连接层、dropout正则化和全局平均池化。
  • Adam 是一种优化器,用于模型训练中调整权重。
  • ImageDataGenerator 是用于图像数据增强的类。
  • regularizers 用于添加正则化项,以防止模型过拟合。

In[5]:

定义了基于MobileNetV2的模型,不包含顶层分类器,然后添加了新的顶层分类器。

base_model = MobileNetV2(weights='imagenet', alpha=1.0, include_top=False, input_shape=(224, 224, 3))
model = Sequential()
model.add(base_model)
model.add(GlobalAveragePooling2D())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.6))
model.add(Dense(3, activation='softmax'))
model.summary()
  • MobileNetV2 被加载并使用ImageNet的预训练权重进行初始化。
  • 新的Sequential模型创建,并添加了全局平均池化层和两个全连接层,最后一个全连接层使用softmax激活函数进行多类分类。

In[6]:

冻结了预训练模型的权重,并编译了整个模型。

base_model.trainable = False
model.compile(optimizer=Adam(lr=0.001, decay=1e-6), loss='categorical_crossentropy', metrics=['accuracy'])
  • 冻结权重意味着在训练过程中,预训练模型的权重不会更新。
  • 使用Adam优化器和交叉熵损失函数编译模型。

In[7]:

准备数据集,将原始数据集分为训练集和验证集。

original_data_dir = '深度学习——系膜部分'
train_data_dir = 'train_data'
validation_data_dir = 'validation_data'
# ... 数据集划分和复制代码 ...
  • 创建了训练和验证数据目录。
  • 从原始数据集中复制图像到相应的训练和验证目录。

In[8]:

使用ImageDataGenerator生成训练和验证数据的流。

train_generator = train_datagen.flow_from_directory('train_data', ... )
validation_generator = test_datagen.flow_from_directory('validation_data', ... )
  • flow_from_directory 方法从指定目录中读取图像,进行数据增强,并生成批次。

In[21]:

定义了模型检查点,以便在验证集准确度提升时保存模型。

checkpoint_path = "best_model"
checkpoint = ModelCheckpoint(checkpoint_path, monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')

In[22]:

训练模型,并使用检查点。

model.fit(train_generator, steps_per_epoch=len(train_generator), epochs=12, ... )
  • 使用fit方法训练模型指定的轮数(epochs),并在每个epoch后使用验证集评估模型。

In[23]:

加载最佳模型并评估其在验证集上的性能。

best_model = tf.keras.models.load_model(checkpoint_path)
test_loss, test_acc = best_model.evaluate(validation_generator, steps=9)

In[24]:

保存模型到HDF5文件。

model.save('your_model.h5')

2.运用保存的最优模型并创建界面

2.1 设计思路

        设计思路是创建一个基于PyQt5的图形用户界面(GUI)应用程序,用于图像识别任务。以下是详细的设计思路:

  1. 项目目标:开发一个用户友好的图像识别系统,该系统允许用户选择图像文件,然后对图像进行分析并显示识别结果。

  2. 技术选择:使用PyQt5作为GUI框架,因为它提供了丰富的组件和良好的跨平台支持。同时,使用TensorFlow和Keras库进行图像处理和模型预测。

  3. 用户界面设计

    • 主窗口:包含标题栏、工具栏、状态栏以及必要的布局控件。
    • 按钮:提供一个按钮让用户选择图像文件。
    • 图像显示区域:用于展示用户选择的图像。
    • 结果显示区:以文本框形式展示预测结果和相关信息。
  4. 功能实现

    • 图像选择:通过 QFileDialog.getOpenFileName 方法打开文件对话框,让用户选择图像文件。
    • 图像显示:使用 QLabel 控件结合 QPixmap 类加载和展示用户选择的图像。
    • 模型加载与预测:加载训练好的模型,对用户选择的图像进行预处理后进行预测。
    • 结果展示:将预测结果以文本形式展示在界面上,并根据结果设置不同的文本颜色。
  5. 图像预处理:将用户选择的图像转换为模型所需的格式,包括调整图像大小、转换为数组、添加批次维度和归一化。

  6. 模型预测:使用加载的模型对预处理后的图像进行预测,获取预测结果。

  7. 结果映射:将模型输出的概率映射到具体的类别名称。

  8. 界面美化:使用 setStyleSheet 方法美化界面元素,如按钮、文本框和标签的样式。

  9. 交互反馈:通过改变文本颜色来直观地反馈预测结果的置信度(如正常、轻度增生、重度增生)。

  10. 应用启动:编写主程序代码,初始化应用程序实例,创建主窗口对象,并进入事件循环。

        整个设计思路围绕创建一个交互性强、反馈直观的GUI应用程序,使用户能够轻松地进行图像识别操作,并获取清晰的结果反馈。

2.2 设计代码

1.导入必要的库:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QFileDialog, QPixmap, QTextEdit
from PyQt5.QtGui import QIcon, QFont
import tensorflow as tf
import numpy as np

MainWindow 是继承自 QMainWindow 的类,它定义了主窗口的布局和行为。

2.定义 MainWindow:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # ... 窗口初始化代码 ...
  • super().__init__(): 调用父类 QMainWindow 的构造函数,初始化窗口。
  • self.setWindowTitle("系膜识别系统"): 设置窗口的标题。
  • self.setGeometry(100, 100, 600, 400): 设置窗口的位置和大小。
  • self.setStyleSheet("background-color: lightblue;"): 设置窗口的背景颜色。

3.设置窗口标题、大小和背景颜色:

self.setWindowTitle("系膜识别系统")
self.setGeometry(100, 100, 600, 400)
self.setStyleSheet("background-color: lightblue;")
  • 创建 QPixmap 对象,加载背景图片。
  • 使用 QLabel 显示背景图片,并调整其大小以适应窗口。

4.设置窗口背景图片:

pixmap = QPixmap("放大镜.png")
self.label = QLabel(self)
self.label.setPixmap(pixmap)
self.label.resize(self.size())
  • 创建一个 QPushButton 对象,设置其文本、位置、大小和样式。
  • 通过 clicked.connect 将按钮的点击事件与 open_image 方法关联。

5.创建“图像选择”按钮并绑定事件:

self.button = QPushButton("图像选择", self)
self.button.setGeometry(125, 20, 150, 30)
self.button.clicked.connect(self.open_image)
  • 创建一个 QLabel 对象用于显示选中的图像。
  • 设置其位置和大小。

6.创建图像显示标签:

self.image_label = QLabel(self)
self.image_label.setGeometry(50, 60, 300, 300)
self.image_label.setStyleSheet("background-color: transparent;")

7.创建结果显示文本框:

self.result_text = QTextEdit(self)
self.result_text.setGeometry(400, 60, 150, 300)
self.result_text.setReadOnly(True)
  • 创建一个 QTextEdit 对象,设置其位置、大小和样式。
  • 设置文本框为只读。

8.open_image 方法:

def open_image(self):
    # ... 文件对话框和图像加载代码 ...
  • 显示文件对话框,让用户选择图像文件。
  • 如果选择了文件,加载图像并显示在 image_label 中。
  • 对图像进行预处理,然后使用加载的模型进行预测。
  • 根据预测结果,设置结果显示在 QTextEdit 中,并改变文本颜色。

9.主程序:

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    icon = QIcon("系膜判别图标.png")
    window.setWindowIcon(icon)
    window.show()
    sys.exit(app.exec())
  • 创建 QApplication 实例,初始化PyQt应用。
  • 创建 MainWindow 的实例 window
  • 设置应用程序图标。
  • 显示窗口并启动事件循环。

3、效果展示及总代码

3.1 效果图

3.2 完整代码

1.模型代码:

import tensorflow as tf
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout,GlobalAveragePooling2D
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from keras import regularizers

# # 加载预训练的MobileNetV2模型,并且不包括顶层分类器
base_model = MobileNetV2(weights='imagenet', alpha=1.0, include_top=False, input_shape=(224, 224, 3))

#from keras.applications import VGG16  # 模型名称
#base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
# 创建一个新的顶层分类器
model = Sequential()
model.add(base_model)
model.add(GlobalAveragePooling2D())
model.add(Dense(512, activation='relu'))  # 增加神经元数量
model.add(Dropout(0.6))
model.add(Dense(3, activation='softmax'))  # 替换num_classes为你的新任务的类别数

# 打印模型结构
model.summary()

# 冻结预训练模型的权重
base_model.trainable = False

# 编译模型
#model.compile(optimizer=Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])

# 编译模型,使用Adam优化器结合权重衰减来减少过拟合
model.compile(optimizer=Adam(lr=0.001, decay=1e-6), 
              loss='categorical_crossentropy', 
              metrics=['accuracy'])

# 准备数据
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

import os
import shutil
from sklearn.model_selection import train_test_split

# 原始数据目录
original_data_dir = '深度学习——系膜部分'

# 新的训练数据目录和验证数据目录
train_data_dir = 'train_data'
validation_data_dir = 'validation_data'

# 创建训练数据目录和验证数据目录
os.makedirs(train_data_dir, exist_ok=True)
os.makedirs(validation_data_dir, exist_ok=True)

if os.path.exists(train_data_dir):
    shutil.rmtree(train_data_dir)
if os.path.exists(validation_data_dir):
    shutil.rmtree(validation_data_dir)

os.makedirs(train_data_dir, exist_ok=True)
os.makedirs(validation_data_dir, exist_ok=True)

# 遍历每个类别的文件夹
for class_name in os.listdir(original_data_dir):
    class_dir = os.path.join(original_data_dir, class_name)
    
    # 创建类别对应的训练集和验证集目录
    os.makedirs(os.path.join(train_data_dir, class_name), exist_ok=True)
    os.makedirs(os.path.join(validation_data_dir, class_name), exist_ok=True)
    
    # 获取该类别下的所有图像文件
    images = os.listdir(class_dir)
    
    # 将图像数据划分为训练集和验证集
    train_images, validation_images = train_test_split(images, test_size=0.3, random_state=42)
    
    # 复制训练集图像到训练集目录
    for image in train_images:
        src = os.path.join(class_dir, image)
        dst = os.path.join(train_data_dir, class_name, image)
        if not os.path.exists(dst):
            shutil.copy(src, dst)

    # 复制验证集图像到验证集目录
    for image in validation_images:
        src = os.path.join(class_dir, image)
        dst = os.path.join(validation_data_dir, class_name, image)
        if not os.path.exists(dst):
            shutil.copy(src, dst)

# 从目录中获取增强后的训练数据和验证数据
train_generator = train_datagen.flow_from_directory(
    'train_data',
    target_size=(224, 224),
    batch_size=3,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    'validation_data',
    target_size=(224, 224),
    batch_size=3,
    class_mode='categorical')

from tensorflow.keras.callbacks import ModelCheckpoint
# 设置模型保存路径和保存条件
checkpoint_path = "best_model"
checkpoint = ModelCheckpoint(checkpoint_path, monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')

# 训练模型
model.fit(train_generator,
          steps_per_epoch=len(train_generator),
          epochs=12,
          validation_data=validation_generator,
          validation_steps=len(validation_generator),
         callbacks=[checkpoint])

# 加载最佳模型
best_model = tf.keras.models.load_model(checkpoint_path)

# 评估模型
test_loss, test_acc = best_model.evaluate(validation_generator, steps=9)
print('Test accuracy:', test_acc)

# 保存为HDF5文件格式
model.save('your_model.h5')

import matplotlib
matplotlib.rcParams['font.family'] = 'SimHei'

best_model = tf.keras.models.load_model('best_model')

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 5))
for i in range(10):
    # 从验证集生成器中获取一个批量的图像数据
    batch = next(validation_generator)
    
    # 选择其中一张图像进行预测和展示
    image = batch[0][0]
    
    # 显示图像
    plt.subplot(2, 5, i+1)
    plt.axis('off')
    plt.imshow(image)
    
    # 调整图像形状以符合模型预测要求
    image = np.expand_dims(image, axis=0)
    
    # 进行预测
    y_pred = np.argmax(best_model.predict(image))
    
    # 显示真实标签值和预测值
    plt.title(f'标签值:{np.argmax(batch[1][0])}\n预测值:{y_pred}')

plt.show()


import tensorflow as tf

# 加载数据集
train_dataset = tf.keras.preprocessing.image_dataset_from_directory(
    'train_data',
    labels='inferred',
    label_mode='int'
)

# 获取类别标签顺序
class_names = train_dataset.class_names
print("类别标签顺序:", class_names)


2.建模代码

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QTextEdit, QFileDialog
from PyQt6.QtGui import QPixmap,QFont
import tensorflow as tf
import numpy as np
from PyQt6.QtGui import QIcon  # 导入QIcon类

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.setWindowTitle("系膜识别系统")
        self.setGeometry(100, 100, 600, 400)#页面总大小
        # 设置窗口背景颜色
        self.setStyleSheet("background-color: lightblue;")
        # 设置窗口背景
        pixmap = QPixmap("放大镜.png")
        self.label = QLabel(self)
        self.label.setPixmap(pixmap)
        self.label.resize(self.size())
        
        self.button = QPushButton("图像选择", self)
        self.button.setGeometry(125, 20, 150, 30)#按钮大小
        self.button.clicked.connect(self.open_image)
        self.button.setStyleSheet("font-size: 16px;")  # 设置按钮字体大小为16px

        self.image_label = QLabel(self)
        self.image_label.setGeometry(50, 60, 300, 300)#显示图片的大小
        self.image_label.setStyleSheet("background-color: transparent;")  # 将背景颜色设置为透明

        self.result_text = QTextEdit(self)
        self.result_text.setGeometry(400, 60, 150, 300)
        self.result_text.setReadOnly(True)
        self.result_text.setStyleSheet("border: 2px dashed lightred;")  # 将外框样式设置为浅绿色的虚线

    def open_image(self):
        filename, _ = QFileDialog.getOpenFileName(self, "图像选择", r"C:\Users\11506\Desktop\计算机\大三下实训\深度学习——系膜部分", "Image Files (*.png *.jpg *.jpeg *.bmp)")


        if filename:
            pixmap = QPixmap(filename)
            self.image_label.setPixmap(pixmap)
            self.image_label.setScaledContents(True)

            # 预处理图像
            image = tf.keras.preprocessing.image.load_img(filename, target_size=(224, 224))
            image = tf.keras.preprocessing.image.img_to_array(image)
            image = np.expand_dims(image, axis=0)
            image = image / 255.0

            # 使用模型进行预测
            # 加载训练好的模型
            model = tf.keras.models.load_model('best_model')
            predictions = model.predict(image)
            class_names = [ '正常','轻度系膜增生', '重度系膜增生']  # 替换为你的类别名称
            result = class_names[np.argmax(predictions)]
            
            # 根据预测结果设置文本颜色
            color_map = { '正常': 'green','轻度系膜增生': 'yellow', '重度系膜增生': 'red'}
            color = color_map.get(result, 'black')
            
            # 设置预测结果显示在 QTextEdit 中,并设置字体样式、大小、颜色以及文本居中
            font = QFont()
            font.setFamily('Brush Script')
            font.setPointSize(50)
            self.result_text.setFont(font)
            self.result_text.setStyleSheet(f"color: {color}; background-color: lightblue; text-align: center;border: 2px dashed lightred;")
            
            self.result_text.setPlainText(result)
            
if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    # 创建主窗口对象
    window = MainWindow()
    
    # 设置图标
    icon = QIcon("系膜判别图标.png")  # 替换为你的图标文件路径
    window.setWindowIcon(icon)
    
    # 显示窗口并启动应用程序事件循环
    window.show()
    sys.exit(app.exec())

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值