三维重建 PyQt Python VTK 医学图像的可视化 vtkImageView2三视图(横断面,冠状面,矢状面)

概述:

本文实现了 Python C++ 版本 的 四视图,MPR 和 三维重建;同时有C++ Qt版本

效果展示:

三维重建 PyQt Python VTK 医学图像的可视化 vtkImageView2三视图(横断面,冠状面,矢状面)_第1张图片

视频展示:

VTK四视图

vtkImageViewer2

一个方便易用的2D图像显示类,它封装了vtkRenderWindow, vtkRender, vtkImageActor和vtkImageMapToWinowLevelColors。同时,包含了一个vtkInteractorStyleImage的交互方式,使得显示和交互变得更加简单。

3D医学图像有很多,不仅只有CT,还有MRI,超声波,X-光等,各具有独特的诊断优势。下面以CT图像数据作为示例:

效果:

三维重建 PyQt Python VTK 医学图像的可视化 vtkImageView2三视图(横断面,冠状面,矢状面)_第2张图片

 1. DICOM 数据读取

    reader = vtk.vtkDICOMImageReader()
    reader.SetDirectoryName("D:/datasource/fei/ScalarVolume_13")
    reader.Update()

2.设置imageViewer
可以设置slice,3维数据的方向,以及窗口大小、窗宽、窗位等等
 

    imageviewer = vtk.vtkImageViewer2()
    imageviewer.SetInputConnection(reader.GetOutputPort())
    interactor = vtk.vtkRenderWindowInteractor()
    imageviewer.SetupInteractor(interactor)  # 添加交互器
    # imageviewer.SetSize(400, 400)
    imageviewer.SetColorLevel(100)  # 窗位
    imageviewer.SetColorWindow(3000)  # 窗宽
    imageviewer.SetSliceOrientationToXY()  # 设置切片方向为XY
    imageviewer.SetSlice(imageviewer.GetSliceMin())  # 设置切片起始位置为切片最小值

all code; 可以设置 :横断面,冠状面,矢状面

import vtk
reader = vtk.vtkDICOMImageReader()
reader.SetDirectoryName("CT")
reader.Update()   
imageviewer = vtk.vtkImageViewer2()
imageviewer.SetInputConnection(reader.GetOutputPort())
interactor = vtk.vtkRenderWindowInteractor()
imageviewer.SetupInteractor(interactor)#添加交互器
#imageviewer.SetSize(400, 400)
imageviewer.SetColorLevel(100)#窗位
imageviewer.SetColorWindow(3000)#窗宽
imageviewer.SetSliceOrientationToXY()#设置切片方向为XY
imageviewer.SetSlice(imageviewer.GetSliceMin())#设置切片起始位置为切片最小值
#imageviewer.SetSliceOrientationToXZ() 
#imageviewer.SetSliceOrientationToYZ() 
#print(imageviewer.GetSliceOrientation())#打印切片方向,XY为2,XZ为1,YZ为0
imageviewer.Render()
interactor.Start()

Using vtkResliceImageViewer or vtkImageViewer2 with Python3+PyQt5

import sys
import vtk
from PyQt5 import QtCore, QtGui
from PyQt5 import QtWidgets

from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent = None):
        QtWidgets.QMainWindow.__init__(self, parent)

        self.frame = QtWidgets.QFrame()
        self.vl = QtWidgets.QVBoxLayout()
        self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
        self.vl.addWidget(self.vtkWidget)

        pathDicomDir = "/path/to/dicom/data"
        reader = vtk.vtkDICOMImageReader()
        reader.SetDirectoryName(pathDicomDir)
        reader.Update()

        self.viewer = vtk.vtkImageViewer()
        # self.viewer = vtk.vtkImageViewer2()
        # self.viewer = vtk.vtkResliceImageViewer()
        self.viewer.SetInputData(reader.GetOutput())

        self.viewer.SetupInteractor(self.vtkWidget)
        self.viewer.SetRenderWindow(self.vtkWidget.GetRenderWindow())
        self.viewer.Render()
        self.frame.setLayout(self.vl)
        self.setCentralWidget(self.frame)

        self.show()


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

C++:

#include "vtkSmartPointer.h"
#include "vtkObjectFactory.h"
#include "vtkRenderWindow.h"
#include "vtkGenericRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkActor.h"

#include "vtkDICOMImageReader.h"
#include "vtkImageViewer2.h"
#include "vtkInteractorStyleImage.h"

class myVtkInteractorStyleImage : public vtkInteractorStyleImage
{
public:
	static myVtkInteractorStyleImage* New();
	vtkTypeMacro(myVtkInteractorStyleImage, vtkInteractorStyleImage);

protected:
	vtkImageViewer2* ImageViewer;
	int Slice;
	int MinSlice;
	int MaxSlice;

public:
	void SetImageViewer(vtkImageViewer2* imageViewer)
	{
		this->ImageViewer = imageViewer;
		this->MinSlice = imageViewer->GetSliceMin();
		this->MaxSlice = imageViewer->GetSliceMax();
		this->Slice = (this->MinSlice + this->MaxSlice) / 2;
		this->ImageViewer->SetSlice(this->Slice);
		this->ImageViewer->Render();
	}

protected:
	virtual void OnMouseWheelForward()
	{
		if (this->Slice < this->MaxSlice)
		{
			this->Slice += 1;
			this->ImageViewer->SetSlice(this->Slice);
			this->ImageViewer->Render();
		}
	}

	virtual void OnMouseWheelBackward()
	{
		if (this->Slice > this->MinSlice)
		{
			this->Slice -= 1;
			this->ImageViewer->SetSlice(this->Slice);
			this->ImageViewer->Render();
		}
	}
};

vtkStandardNewMacro(myVtkInteractorStyleImage);

int main(int argc, char* argv[])
{
	if (argc < 2)
	{
		std::cout << "Usage: " << argv[0] << " DicomDirectory" << std::endl;
		return EXIT_FAILURE;
	}

	auto reader = vtkSmartPointer::New();
	reader->SetDirectoryName(argv[1]);
	reader->Update();

	auto imageViewer = vtkSmartPointer::New();
	imageViewer->SetInputConnection(reader->GetOutputPort());

	auto interactor = vtkSmartPointer::New();
	imageViewer->SetupInteractor(interactor);
	imageViewer->SetSize(400, 400);
	imageViewer->SetColorLevel(500);
	imageViewer->SetColorWindow(1000);
	imageViewer->SetSliceOrientationToXY();
	imageViewer->GetRenderer()->SetBackground(1, 1, 1);

	auto myStyle = vtkSmartPointer::New();
	myStyle->SetImageViewer(imageViewer);
	interactor->SetInteractorStyle(myStyle);

	imageViewer->Render();
	imageViewer->GetRenderer()->ResetCamera();
	imageViewer->Render();

	interactor->Start();

	return EXIT_SUCCESS;
}

你可能感兴趣的:(Python,VTK,pyqt,Python,VTK,MPR,三维重建)