欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MaskRCNN可视化界面开发(PyQt5)

程序员文章站 2022-04-10 13:50:31
MaskRCNN可视化界面开发(PyQt5)笔者因毕设要求,需要对maskRCNN进行封装,制作一个可视化界面。先来展示下效果图:文章目录MaskRCNN可视化界面开发(PyQt5)前言一、PyQt5及Designer、Pyuic插件安装二、设计UI界面1.使用Qt Designer来设计界面2.按钮事件3.ui文件转py代码三、编写逻辑代码前言本文默认已经实现了MaskRCNN的训练和测试,现在测试的基础上加一个UI界面。本文使用PyQt5进行界面开发。提示:以下是本篇文章正文...

MaskRCNN可视化界面开发(PyQt5)

笔者因毕设要求,需要对maskRCNN进行封装,制作一个可视化界面。


先来展示下效果图:
MaskRCNN可视化界面开发(PyQt5)


前言

本文默认已经实现了MaskRCNN的训练和测试,现在测试的基础上加一个UI界面。 本文使用PyQt5进行界面开发。

提示:以下是本篇文章正文内容,下面案例可供参考

一、PyQt5及Designer、Pyuic插件安装

1.激活maskRCNN虚拟环境,安装PyQt5:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package PyQt5

清华的镜像地址,加速下载,推荐使用

PyQt5 测试

import sys
from PyQt5 import QtWidgets

app = QtWidgets.QApplication(sys.argv)
widget = QtWidgets.QWidget()
widget.resize(360, 360)
widget.setWindowTitle("Hello, PyQt5")
widget.show()
sys.exit(app.exec_())

MaskRCNN可视化界面开发(PyQt5)
2.安装Qt的工具包

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package PyQt5-tools 

安装成功打开python的安装目录的Lib目录下,site-packages里面会有 PyQt5pyqt5-tools 两个目录

配置PyChram,安装QtDesigner:
2.1打开PyCharm,File > Settings > Tools > External Tools
MaskRCNN可视化界面开发(PyQt5)
2.2点击 + 号创建
Name: Designer
Group: Qt
Program: designer.exe所在目录
Working directory: $ProjectFileDir$
MaskRCNN可视化界面开发(PyQt5)
2.3安装Pyuic
打开PyCharm,File > Settings > Tools > External Tools
点击 + 号创建
Name: Pyuic
Group: Qt
Program: python.exe所在目录
Arguments: -m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py
Working directory: $FileDir$

MaskRCNN可视化界面开发(PyQt5)

二、设计UI界面

1.使用Qt Designer来设计界面

注意本过程需在maskRCNN源码的同一目录下进行。

按照我们之前的界面构思
MaskRCNN可视化界面开发(PyQt5)
我们需要从3个PushButton按键,2个label用于展示和1个textBrowser用于状态显示。
控件上显示的文字 text 属性和控件的名字 objectName 属性需要修改,便于显示和代码调用。可以按照下面我推荐的命名:

控件 显示内容text 控件名objectName
PushButton 导入图片 btnInput
PushButton 检测 btnTest
PushButton 保存 btnSave
Label 输入图片 labelinput
Label 结果图片 labelresult
TextBrowser textBrowser

2.按钮事件

我们知道GUI是通过事件驱动的,什么意思呢?比如前面我们已经设计好了界面,接下来就需要实现”导入图片”到”保存”这3个按钮的功能,也就是给每个按钮指定一个”函数”,逻辑代码写在这个函数里面。这种函数就称为事件,Qt中称为槽连接。
点击Designer工具栏的”Edit Signals/Slots”按钮,进入槽函数编辑界面,点击旁边的”Edit Widgets”可以恢复正常视图:
MaskRCNN可视化界面开发(PyQt5)
进入槽函数编辑界面后,然后点击按钮并拖动,当产生类似于电路中的接地符号时释放鼠标,参看下图:
MaskRCNN可视化界面开发(PyQt5)
到此,我们就完成了界面设计的所有工作,按下Ctrl+S保存当前窗口为.ui文件。

3.ui文件转py代码

MaskRCNN可视化界面开发(PyQt5)
运行PyUIC后,会生成UI个.py文件,打开.py就是我们需要的界面模板。注意不要直接在.py文件里编码,因为每一次运行PyUIC,生成的.py文件都会更新,添加的代码不会保存。

三、编写逻辑代码

在同一工作目录下新建一个”UI_main.py”的文件,存放逻辑代码。代码中的每部分我都写得比较独立,没有封装成函数,便于理解。代码看上去很长,但很简单,可以每个模块单独看。

我整体的思路比较简单:
1.当按下导入图片按键时,要导入的图片显示在待显示的label区域;
2.当按下导入检测按键时,运行原来的maskRCNN的测试部分的代码,并将测试部分的结果图片保存为temp.png,并显示在结果显示的label区域;
3.当按下导入保存按键时,读取temp.png图片,保存到指定位置。
4.以上三部步都会产生反馈状态,将反馈状态显示在textBrowser区域。
下面直接上代码:

import sys
import cv2 as cv

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
# from PyQt5.QtWidgets import QFileDialog, QMainWindow
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QApplication

from untitled import Ui_MainWindow


class PyQtMainEntry(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.setWindowTitle("路面缺陷检测软件V1.0")

        self.labelinput.setAlignment(Qt.AlignCenter)
        self.labelinput.setStyleSheet("QLabel{background:gray;}"
                                      "QLabel{color:rgba(255,255,255,150);"
                                      "font-size:20px;"
                                      "font-weight:bold;"
                                      "font-family:Roman times;}")

        self.labelresult.setAlignment(Qt.AlignCenter)
        self.labelresult.setStyleSheet("QLabel{background:gray;}"
                                       "QLabel{color:rgba(255,255,255,150);"
                                       "font-size:20px;"
                                       "font-weight:bold;"
                                       "font-family:Roman times;}")

    def btnTest_Pressed(self):
        if not hasattr(self, "captured"):
            # print("没有输入图像")
            # self.textBrowser.setPlainText("没有输入图像")
            return
        self.textBrowser.append("图像检测中...")



    def btnInput_Clicked(self):
        '''
        从本地读取图片
        '''
        global fname
        # 打开文件选取对话框
        filename, _ = QFileDialog.getOpenFileName(self, '打开图片', "", "*.jpg;;*.png;;All Files(*)")
        if filename:
            self.captured = cv.imread(str(filename))
            # OpenCV图像以BGR通道存储,显示时需要从BGR转到RGB
            self.captured = cv.cvtColor(self.captured, cv.COLOR_BGR2RGB)

            rows, cols, channels = self.captured.shape
            bytesPerLine = channels * cols
            QImg = QImage(self.captured.data, cols, rows, bytesPerLine, QImage.Format_RGB888)
            self.labelinput.setPixmap(QPixmap.fromImage(QImg).scaled(
                self.labelinput.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
        fname = filename
        print(fname)
        self.textBrowser.setPlainText("成功打开图片")

    def btnTest_Clicked(self):
        '''
        test
        '''
        global fname
        # 如果没有捕获图片,则不执行操作
        if not hasattr(self, "captured"):
            print("没有输入图像")
            self.textBrowser.setPlainText("没有输入图像")
            return
        print("start")
        print(fname.split("/")[-1])
        # -*- coding: utf-8 -*-
        import os
        import sys
        import skimage.io
        import matplotlib
        matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
        matplotlib.rcParams['font.serif'] = ['KaiTi']
        from mrcnn.config import Config
        from datetime import datetime

        # Root directory of the project
        ROOT_DIR = os.getcwd()

        # Import Mask RCNN
        sys.path.append(ROOT_DIR)  # To find local version of the library
        from mrcnn import utils
        import mrcnn.model as modellib
        from mrcnn import visualize

        # Import COCO config
        # sys.path.append(os.path.join(ROOT_DIR, "samples/coco/"))  # To find local version
        # from samples.coco import coco

        # Directory to save logs and trained model
        MODEL_DIR = os.path.join(ROOT_DIR, "logs")

        # Local path to trained weights file
        # todo:模型位置
        COCO_MODEL_PATH = "E:\\maskrcnn_pycharm\\Mask_RCNN\\logs\\mask_rcnn_shapes_1000.h5"  # 模型保存目录
        # Download COCO trained weights from Releases if needed
        if not os.path.exists(COCO_MODEL_PATH):
            utils.download_trained_weights(COCO_MODEL_PATH)
            print("cuiwei***********************")

        # Directory of images to run detection on
        # todo:测试图片位置
        # IMAGE_DIR = os.path.join(ROOT_DIR, "picRGB")
        IMAGE_DIR = fname

        print(IMAGE_DIR)

        class ShapesConfig(Config):
            """Configuration for training on the toy shapes dataset.
            Derives from the base Config class and overrides values specific
            to the toy shapes dataset.
            """
            # Give the configuration a recognizable name
            NAME = "shapes"

            # Train on 1 GPU and 8 images per GPU. We can put multiple images on each
            # GPU because the images are small. Batch size is 8 (GPUs * images/GPU).
            GPU_COUNT = 1
            IMAGES_PER_GPU = 1

            # Number of classes (including background)
            NUM_CLASSES = 1 + 6  # background + 3 shapes

            # Use small images for faster training. Set the limits of the small side
            # the large side, and that determines the image shape.
            IMAGE_MIN_DIM = 320
            IMAGE_MAX_DIM = 512

            # Use smaller anchors because our image and objects are small
            RPN_ANCHOR_SCALES = (8 * 6, 16 * 6, 32 * 6, 64 * 6, 128 * 6)  # anchor side in pixels

            # Reduce training ROIs per image because the images are small and have
            # few objects. Aim to allow ROI sampling to pick 33% positive ROIs.
            TRAIN_ROIS_PER_IMAGE = 100

            # Use a small epoch since the data is simple
            STEPS_PER_EPOCH = 100

            # use small validation steps since the epoch is small
            VALIDATION_STEPS = 50

        # import train_tongue
        # class InferenceConfig(coco.CocoConfig):
        class InferenceConfig(ShapesConfig):
            # Set batch size to 1 since we'll be running inference on
            # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU
            GPU_COUNT = 1
            IMAGES_PER_GPU = 1

        config = InferenceConfig()

        # Create model object in inference mode.
        model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config)

        # Load weights trained on MS-COCO
        model.load_weights(COCO_MODEL_PATH, by_name=True)

        # COCO Class names
        # Index of the class in the list is its ID. For example, to get ID of
        # the teddy bear class, use: class_names.index('teddy bear')
        # class_names = ['BG', '隐裂']  # 注意修改类别名称
        class_names = ['BG', '灌缝修补', '横向裂缝', '块状裂缝', '块状修补', '纵向裂缝', '坑槽']
        # Load a random image from the images folder
        # file_names = next(os.walk(IMAGE_DIR))[2]
        # image = skimage.io.imread("E:\\maskrcnn_pycharm\\Mask_RCNN\\picRGB\\62.png")  # 你想要测试的图片
        image = skimage.io.imread(fname)  # 你想要测试的图片

        a = datetime.now()
        # Run detection
        results = model.detect([image], verbose=1)
        # print("result:",results)
        b = datetime.now()
        # Visualize results
        # print("检测用时", (b - a).seconds)
        time = (b - a).seconds
        self.textBrowser.append("检测用时:" + str(time) + "s")
        r = results[0]
        visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'],
                                    class_names, r['scores'])

        class_ids = r['class_ids']

        class_dict = {}
        for index, i in enumerate(class_ids):
            if i in class_dict:
                class_dict[i] += 1
            else:
                class_dict[i] = 1

        output_dict = {}

        for key, value in class_dict.items():
            label = class_names[key]
            output_dict[label] = value
        print(output_dict)
        self.textBrowser.append("本张路面图片包含:" )
        for key, value in output_dict.items():
            self.textBrowser.append(str(value)+"处"+str(key))

        self.captured = cv.imread(r"temp.png")
        # OpenCV图像以BGR通道存储,显示时需要从BGR转到RGB
        self.captured = cv.cvtColor(self.captured, cv.COLOR_BGR2RGB)

        rows, cols, channels = self.captured.shape
        bytesPerLine = channels * cols
        QImg = QImage(self.captured.data, cols, rows, bytesPerLine, QImage.Format_RGB888)
        self.labelresult.setPixmap(QPixmap.fromImage(QImg).scaled(
            self.labelresult.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))

        self.textBrowser.append("检测完成")

    def btnSave_Clicked(self):
        '''
        保存
        '''
        global fname
        if not hasattr(self, "captured"):
            print("没有输入图像")
            self.textBrowser.setPlainText("没有输入图像")
            return
        tmp = fname.split('/')[-1]
        img = cv.imread("temp.png")
        fd, type = QFileDialog.getSaveFileName(self,
                                               "保存图片", tmp)
        print(fd)
        cv.imwrite(fd, img)
        # self.textBrowser.setPlainText("保存成功")
        self.textBrowser.append("保存成功")  # textedit是文本框的名称

        print("保存成功")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = PyQtMainEntry()
    window.show()
    sys.exit(app.exec_())

今天就先写到这边,后续有想法再补充!
如果阅读本文对你有用,欢迎点赞评论收藏呀!!!
2020年12月8日15:32:30

本文地址:https://blog.csdn.net/JulyLi2019/article/details/110850627