pyqt combines deep learning framework to build system

After nearly two months, I, Hu Hansan, am back! ! ! I played for nearly two months, had interviews for half a month, and worked hard for half a month (with results) and submitted a paper (under external review, a disease identification model based on the improvement of deep learning neural networks).

After several fierce battles to find an internship job:

1. Tester Engineer (Software Test Engineer)

2. Image algorithm engineer

       In the end, I found that internships are actually not that difficult to find. I only had one interview among several interviews, and I received offers for the others. But because I am in a restricted area, I only looked for a job in that city, and the job positions were limited. There were not many options, and there were not many good companies. After all, the big army only really started working in September after the summer vacation. Fight.

       I finally chose a relatively suitable company and officially reported for internship on July 17th, but they all required long-term internships, which is the same problem for every company. If you don’t have enough time, it is not recommended to try it lightly, because you haven’t joined the job yet, and you don’t know how easy it will be after joining the job, how long you can do it, and whether it will be useful in the future. (The only purpose of my internship is actually to become a full-time employee through the internship. The premise is that it is a company that I am satisfied with), so I can only go to the pit first to give everyone a try. After the internship is over, I will share my experience. Now I ask if you have any Internship required? I have no idea! ! !

Study preparation experience:

If you want to interview a software testing engineer, you don’t just need to read a little bit. What is this? Isn't it just a test? Do you need to write code? I once thought it was easy, and also once thought it was difficult. It’s really hard to understand this if you don’t learn it carefully. I recommend a must-see video.

Qianfeng software testing must-see video

Image algorithms and visual algorithms rely on everyone's daily accumulation. You must know traditional algorithms (opencv library), deep learning frameworks, and the language python is a must. All languages ​​including software testing must also be known, including c and c++. . This prospect is still good, don’t listen to other people, what is best is what you know, you can work like a fish in water and the salary is high.

       I had a physical examination today, and I had a blood test and met a new intern. In the end, the bruise turned purple or even black (I was a guinea pig, ugh*_*) and I will have to carry a lot of luggage to a new city. I’m scared and looking forward to it, my new chapter is about to begin!

Finally, here comes the benefit:

(I don’t forget to learn even though I’m eating dirt. I combined pyqt with the recognition model trained by deep learning before, and realized the interface, which can be used as a system.)

Login, registration, and home page are implemented. Flexible switching of three pages. The main page is as shown below, which realizes the function of uploading original pictures and disease identification.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton,QLabel,QTextEdit,QFileDialog,QHBoxLayout,QVBoxLayout,QSplitter,QComboBox,QSpinBox
from PyQt5.Qt import QWidget, QColor,QPixmap,QIcon,QSize,QCheckBox
# 导入login.py、main.py里面全部内容
import DengLu
import my_ui
import ZuCe
import os
from PyQt5.QtCore import Qt

import matplotlib.pyplot as plt
import numpy as np
import torch
from torch import nn

from nets import get_model_from_name
from utils.utils import (cvtColor, get_classes, letterbox_image,
                         preprocess_input, show_config)
from PIL import Image
from torchvision import transforms,models


class Classification(object):
    _defaults = {
        # --------------------------------------------------------------------------#
        #   使用自己训练好的模型进行预测一定要修改model_path和classes_path!
        #   model_path指向logs文件夹下的权值文件,classes_path指向model_data下的txt
        #   如果出现shape不匹配,同时要注意训练时的model_path和classes_path参数的修改
        # --------------------------------------------------------------------------#
        # "model_path"        : 'logs/resnet_CBAM-100-best_epoch_weights-loss0.117-val_loss0.009.pth',
        "model_path": 'logs/mobilenetv2-100-ep050-best-loss0.418-val_loss0.078.pth',
        #   所用模型种类:
        "backbone": 'mobilenetv2',
        # --------------------------------------------------------------------#
        #   mobilenetv2、
        #   resnet18、resnet34、resnet50、resnet101、resnet152
        #   vgg11、vgg13、vgg16、vgg11_bn、vgg13_bn、vgg16_bn、
        #   vit_b_16、
        #   swin_transformer_tiny、swin_transformer_small、swin_transformer_base
        "classes_path": 'model_data/cls_classes.txt',
        # --------------------------------------------------------------------#
        #   输入的图片大小
        # --------------------------------------------------------------------#
        "input_shape": [224, 224, 3],

        # --------------------------------------------------------------------#
        #   该变量用于控制是否使用letterbox_image对输入图像进行不失真的resize
        #   否则对图像进行CenterCrop
        # --------------------------------------------------------------------#
        "letterbox_image": False,
        # -------------------------------#
        #   是否使用Cuda
        #   没有GPU可以设置成False
        # -------------------------------#
        "cuda": True
    }

    @classmethod
    def get_defaults(cls, n):
        if n in cls._defaults:
            return cls._defaults[n]
        else:
            return "Unrecognized attribute name '" + n + "'"

    # ---------------------------------------------------#
    #   初始化classification
    # ---------------------------------------------------#
    def __init__(self, **kwargs):
        self.__dict__.update(self._defaults)
        for name, value in kwargs.items():
            setattr(self, name, value)

        # ---------------------------------------------------#
        #   获得种类
        # ---------------------------------------------------#
        self.class_names, self.num_classes = get_classes(self.classes_path)
        self.generate()

        show_config(**self._defaults)

    # ---------------------------------------------------#
    #   获得所有的分类
    # ---------------------------------------------------#
    def generate(self):
        # ---------------------------------------------------#
        #   载入模型与权值
        # ---------------------------------------------------#
        if self.backbone not in ['vit_b_16', 'swin_transformer_tiny', 'swin_transformer_small',
                                 'swin_transformer_base']:
            self.model = get_model_from_name[self.backbone](num_classes=self.num_classes, pretrained=False)
        else:
            self.model = get_model_from_name[self.backbone](input_shape=self.input_shape, num_classes=self.num_classes,
                                                            pretrained=False)
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        self.model.load_state_dict(torch.load(self.model_path, map_location=device))
        self.model = self.model.eval()
        print('{} model, and classes loaded.'.format(self.model_path))

        if self.cuda:
            self.model = nn.DataParallel(self.model)
            self.model = self.model.cuda()

    # ---------------------------------------------------#
    #   检测图片
    # ---------------------------------------------------#
    def detect_image(self, image):
        # ---------------------------------------------------------#
        #   在这里将图像转换成RGB图像,防止灰度图在预测时报错。
        #   代码仅仅支持RGB图像的预测,所有其它类型的图像都会转化成RGB
        # ---------------------------------------------------------#
        image = cvtColor(image)
        # ---------------------------------------------------#
        #   对图片进行不失真的resize
        # ---------------------------------------------------#
        image_data = letterbox_image(image, [self.input_shape[1], self.input_shape[0]], self.letterbox_image)
        # ---------------------------------------------------------#
        #   归一化+添加上batch_size维度+转置
        # ---------------------------------------------------------#
        image_data = np.transpose(np.expand_dims(preprocess_input(np.array(image_data, np.float32)), 0), (0, 3, 1, 2))

        with torch.no_grad():
            photo = torch.from_numpy(image_data)
            if self.cuda:
                photo = photo.cuda()
            # ---------------------------------------------------#
            #   图片传入网络进行预测
            # ---------------------------------------------------#
            preds = torch.softmax(self.model(photo)[0], dim=-1).cpu().numpy()
        # ---------------------------------------------------#
        #   获得所属种类
        # ---------------------------------------------------#
        class_name = self.class_names[np.argmax(preds)]
        probability = np.max(preds)

        # ---------------------------------------------------#
        #   绘图并写字
        # ---------------------------------------------------#
        plt.subplot(1, 1, 1)
        plt.imshow(np.array(image))
        plt.title('Class:%s Probability:%.3f' % (class_name, probability))
        plt.show()
        # plt.imsave(.../img,back.jpg)

        img_data = np.array(image)
        # 保存图像
        plt.imsave('back.png', img_data)

        return class_name


class my_ui(my_ui.Ui_MainWindow, QMainWindow):
    def __init__(self):
        super(my_ui, self).__init__()
        self.setupUi(self)  # 初始化

        # 每写一个按钮链接对应的让它做啥可以在下面添加一个函数
        # 返回登录页slot_btn_function
        self.pushButton_back.clicked.connect(self.slot_btn_function)
        # 选择图片打开上传图片select_image
        self.pushButton_openimg.clicked.connect(self.select_image)
     
        # 开始识别按钮链接
        self.pushButton_6.clicked.connect(self.on_btn_Recognize_Clicked2)

    def slot_btn_function(self):
        self.hide()
        self.f = DengLu()
        self.f.show()

    def select_image(self):
        global fname
        imgName, imgType = QFileDialog.getOpenFileName(self, "打开图片", "", "*.png;;*.jpg;;All Files(*)")
        jpg = QtGui.QPixmap(imgName).scaled(self.label.width(), self.label.height())
        # jpg = QtGui.QPixmap(imgName)
        self.label.setPixmap(jpg)
        fname = imgName
        print(fname)



    def on_btn_Recognize_Clicked2(self):
        classfication = Classification()

        while True:
            global fname
            # savePath = fname
            img = os.path.abspath(fname)
            print("图像的绝对路径:",img)

            # img = input('Input image filename:')
            try:
                image = Image.open(img)
            except:
                print('Open Error! Try again!')
                self.textBrowser.setText("请先上传待测图片!")
                continue
            else:
                class_name = classfication.detect_image(image)
                print("识别结果为:" + class_name)
                if class_name == "rot":
                    class_name = "褐腐病\r\n灰斑病常发病于秋季,初期病斑呈黄褐色圆形状且边缘清晰,病后期病斑区域不断扩大呈现不规则状,病斑区域密集相连加快叶片枯萎。"
                elif class_name == "scab":
                    class_name = "黑星病黑\r\n星病病斑初期呈淡黄色圆形或放射状,逐渐变为棕色,最终变为黑色,病叶上常有多个斑点相互融合,病部干枯开裂,叶柄上的病斑通常是长条状的。"

                elif class_name == "rust":
                    class_name = "雪松锈病\r\n雪松锈病初期病斑呈明亮的桔红色,随后为圆型,边缘为红色病斑呈橙色;患病后期,叶片上病斑逐渐增多,表面呈现密集的小颗粒黄色状病斑。"

                self.textBrowser.setText("识别结果为:" + class_name)
            #  break跳出循环
            break

        # self.edit.setText('识别结果为:' str(txt))


class DengLu(DengLu.Ui_Form, QMainWindow):
    def __init__(self):
        super(DengLu, self).__init__()
        self.setupUi(self)

        # 每写一个按钮链接对应的让它做啥可以在下面添加一个函数
        '''定义跳转到主页按钮'''
        self.btn_login.clicked.connect(self.tiaozhuanzhuye)
        '''定义跳转到注册页按钮'''
        self.btn_login_zuce.clicked.connect(self.tiaozhuanzuce)

    def tiaozhuanzhuye(self):
        self.hide()
        self.f = my_ui()
        self.f.show()
    def tiaozhuanzuce(self):
        self.hide()
        self.f = Ui_ZuCe()
        self.f.show()



class Ui_ZuCe(ZuCe.Ui_Form, QMainWindow):
    def __init__(self):
        super(Ui_ZuCe, self).__init__()
        self.setupUi(self)

        # 每写一个按钮链接对应的让它做啥可以在下面添加一个函数
        self.btn_back.clicked.connect(self.slot_btn_function)
    def slot_btn_function(self):
        self.hide()
        self.f = DengLu()
        self.f.show()


if __name__ == '__main__':
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)  # 支持高分屏自动缩放
    app = QApplication(sys.argv)

    # 为my_ui_window类和login_window类创建对象
    # main_window = main()

    login_window = DengLu()
    classification = Classification()
    zuce_window = Ui_ZuCe()
    my_ui_window = my_ui()

    # 显示登陆窗口
    login_window.show()


    # 关闭程序,释放资源
    sys.exit(app.exec_())

Guess you like

Origin blog.csdn.net/m0_63172128/article/details/131689158