Pyqt5+matplotlib+NIFTI(nii)图像显示(2)显示融合图像

配置Gui

承接上文,在原有的Gui文件上添加一个push button和两个radio button控件,并将其中一个radio button默认checked选中

 

 

将Gui文件转换为py文件



from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(1010, 774)
        self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(630, 700, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(280, 0, 721, 541))
        self.groupBox.setObjectName("groupBox")
        self.widget = QtWidgets.QWidget(self.groupBox)
        self.widget.setGeometry(QtCore.QRect(50, 30, 611, 451))
        self.widget.setObjectName("widget")
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(70, 80, 111, 41))
        self.pushButton.setObjectName("pushButton")
        self.horizontalSlider = QtWidgets.QSlider(Dialog)
        self.horizontalSlider.setGeometry(QtCore.QRect(580, 580, 160, 22))
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setObjectName("horizontalSlider")
        self.pushButton_2 = QtWidgets.QPushButton(Dialog)
        self.pushButton_2.setGeometry(QtCore.QRect(70, 160, 111, 41))
        self.pushButton_2.setObjectName("pushButton_2")
        self.widget_2 = QtWidgets.QWidget(Dialog)
        self.widget_2.setGeometry(QtCore.QRect(330, 110, 611, 451))
        self.widget_2.setObjectName("widget_2")
        self.radioButton = QtWidgets.QRadioButton(Dialog)
        self.radioButton.setGeometry(QtCore.QRect(70, 260, 115, 19))
        self.radioButton.setObjectName("radioButton")
        self.radioButton_2 = QtWidgets.QRadioButton(Dialog)
        self.radioButton_2.setGeometry(QtCore.QRect(70, 300, 115, 19))
        self.radioButton_2.setObjectName("radioButton_2")

        self.retranslateUi(Dialog)
        self.buttonBox.accepted.connect(Dialog.accept)
        self.buttonBox.rejected.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.groupBox.setTitle(_translate("Dialog", "GroupBox"))
        self.pushButton.setText(_translate("Dialog", "加载nii图像"))
        self.pushButton_2.setText(_translate("Dialog", "加载mask图像"))
        self.radioButton.setText(_translate("Dialog", "RadioButton"))
        self.radioButton_2.setText(_translate("Dialog", "RadioButton"))

 嵌入matplotlib的文件没有变化

import matplotlib
matplotlib.use("Qt5Agg")  # 声明使用QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure


class MyFigure(FigureCanvas):
    def __init__(self,width=5, height=4, dpi=100):
        #第一步:创建一个创建Figure
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        #第二步:在父类中激活Figure窗口
        super(MyFigure,self).__init__(self.fig) #此句必不可少,否则不能显示图形
        #第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
        self.axes = self.fig.add_subplot(111)

编写main.py

# This is a sample Python script.

# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.


from PyQt5.QtWidgets import *
import sys
from MyDialog import Ui_Dialog#导入GUI文件
from MyFigure import *#嵌入了matplotlib的文件
from pathlib import Path
import nibabel as nib

class MainDialogImgBW(QDialog,Ui_Dialog):
    def __init__(self):
        super(MainDialogImgBW,self).__init__()
        self.setupUi(self)
        self.setWindowTitle("显示nii图像")
        self.setMinimumSize(0,0)

        #创建存放nii文件路径的属性
        self.nii_path=''
        #创建存放mask文件路径的属性
        self.mask_path = ''
        #创建记录nii文件里面图片数量的属性
        self.shape=1
        #创建用于检查radio button选择标记的属性,选择'nii图像',为0,现在‘mask图像’,为1
        self.check = 0

        #定义MyFigure类的一个实例
        self.F = MyFigure(width=3, height=2, dpi=100)
        #在GUI的groupBox中创建一个布局,用于添加MyFigure类的实例(即图形)后其他部件。
        self.gridlayout = QGridLayout(self.groupBox)  # 继承容器groupBox
        self.gridlayout.addWidget(self.F,0,1)
        self.pushButton.clicked.connect(self.bindButton)
        self.pushButton_2.clicked.connect(self.bindButton2)
        self.horizontalSlider.valueChanged.connect(self.bindSlider)
        self.radioButton.clicked.connect(self.bindradiobutton)
        self.radioButton_2.clicked.connect(self.bindradiobutton)

    def showimage(self,slice_idx):
        data_nii = nib.load(Path(self.nii_path))
        data1=data_nii.get_fdata()
        self.shape = data1.shape[-1]
        self.horizontalSlider.setRange(1,data1.shape[-1])
        if not self.mask_path=='':
            data_mask = nib.load(Path(self.mask_path))
            data2 = data_mask.get_fdata()

        fig = self.F.figure
        fig.clear()
        ax = fig.add_subplot(111)  # 将画布划成1*1的大小并将图像放在1号位置,给画布加上一个坐标轴
        ax.imshow(data1[:, :, slice_idx - 1], cmap='gray')
        #将mask的矩阵转换,未勾画区为透明的,勾画区为红色
        if self.check==1:
            array1 = list(data2[:, :, slice_idx - 1])
            a = len(array1)
            b = len(array1[0])
            pic = [[0] * b for i in range(a)]
            for i in range(0,a):
                for j in range(0,b):
                    if array1[i][j] == 0:
                        pic[i][j] = [0, 0, 0, 0]
                    else:
                        pic[i][j] = [255, 0, 0, 100]

            ax.imshow(pic, cmap='viridis')
            del array1
            del pic
        fig.canvas.draw()

    def bindradiobutton(self):
        if self.radioButton.isChecked():
            self.check = 0
        else:
            self.check = 1
        slice_idx = self.horizontalSlider.value()
        self.showimage(slice_idx)

    def bindSlider(self):
        slice_idx = self.horizontalSlider.value()
        self.showimage(slice_idx)

    def bindButton(self):
        file_name = QFileDialog.getOpenFileName(None, "Open File", "./", "nii(*.nii.gz;*.nii)")
        self.nii_path = file_name[0]
        slice_idx = self.horizontalSlider.value()
        self.showimage(slice_idx)

    def bindButton2(self):
        file_name = QFileDialog.getOpenFileName(None, "Open File", "./", "nii(*.nii.gz;*.nii)")
        self.mask_path = file_name[0]

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = MainDialogImgBW()
    main.show()
    sys.exit(app.exec_())

效果展示

 

这是一个基础代码,仅供参考: ``` python import vtk from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * import sys class VTKWidget(QWidget): def __init__(self, parent=None): super(VTKWidget, self).__init__(parent) # 创建VTK渲染器 self.renderer = vtk.vtkRenderer() self.renderer.SetBackground(0.2, 0.2, 0.2) # 创建VTK交互器 self.interactor = vtk.vtkRenderWindowInteractor() self.interactor.SetRenderWindow(self.render_window) # 创建VTK渲染窗口 self.render_window = vtk.vtkRenderWindow() self.render_window.AddRenderer(self.renderer) # 创建VTK渲染窗口控件 self.vtk_widget = QVTKRenderWindowInteractor(self) self.layout = QVBoxLayout(self) self.layout.addWidget(self.vtk_widget) # 设置VTK交互器 self.vtk_widget.SetRenderWindow(self.render_window) self.interactor.Initialize() def load_dataset(self, filename): # 创建VTK读取器 reader = vtk.vtkDICOMImageReader() reader.SetFileName(filename) # 创建VTK体绘制器 volume_mapper = vtk.vtkGPUVolumeRayCastMapper() volume_mapper.SetInputConnection(reader.GetOutputPort()) # 创建VTK体视图器 volume_property = vtk.vtkVolumeProperty() volume_property.SetColor(vtk.vtkColorTransferFunction()) volume_property.SetScalarOpacity(vtk.vtkPiecewiseFunction()) volume_property.ShadeOn() volume_property.SetInterpolationTypeToLinear() volume = vtk.vtkVolume() volume.SetMapper(volume_mapper) volume.SetProperty(volume_property) # 将VTK体视图器添加到VTK渲染器 self.renderer.AddVolume(volume) self.renderer.ResetCamera() self.render_window.Render() self.interactor.Start() def save_as_nii_gz(self, filename): # 创建VTK图像数据对象 image_data = vtk.vtkImageData() # 将VTK图像数据对象保存为.nii.gz文件 writer = vtk.vtkNIFTIImageWriter() writer.SetFileName(filename) writer.SetInputData(image_data) writer.Write() if __name__ == '__main__': app = QApplication(sys.argv) widget = VTKWidget() widget.load_dataset('example.dcm') widget.save_as_nii_gz('example.nii.gz') sys.exit(app.exec_()) ``` 需要注意的是,这段代码中的VTK渲染器、VTK交互器、VTK渲染窗口、VTK渲染窗口控件等对象的创建顺序和相互关系非常重要。此外,这段代码中的VTK体绘制器、VTK体视图器、VTK体绘制属性等对象的创建也需要根据实际需求进行调整。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值