Advertisement

VTK笔记——医学图像的可视化与交互(vtkImageViewer2)

阅读量:

在解析了医学图像数据之后,就需要将其展示出来并配合互动操作.三维数据经过平面化处理后实现二维呈现,并配合不同切面切换辅助医学分析.

vtkImageViewer2

该类提供了一个便捷易用的二维图像显示功能。它集成了一系列关键的VTK组件包括vtkRenderWindow vtkRender vtkImageActor以及vtkImageMapToWinowLevelColors这些组件为用户提供了一整套完整的功能架构。同时该软件支持基于vtkInteractorStyleImage的交互界面从而显著简化了数据展示与用户交互的过程。

3D医学图像的种类繁多,在除了传统的CT之外还有MRI、超声波和X-射线等技术,并且每种方法都有其独特的优势。
以下部分将介绍如何通过 DICOM 格式的医学影像数据进行处理。
在ITK框架中支持使用 DICOM 图像进行读取,并且 VTK 也同样提供了相应的功能模块。
例如,在ITK中可以通过 itk::ReadDicomImageFilter 实现这一功能;而 VTK 则可以通过 vtkDICOMImageReader 来完成同样的操作。

复制代码
    	auto reader = vtkSmartPointer<vtkDICOMImageReader>::New();
    	reader->SetDirectoryName(argv[1]);
    	reader->Update();

请在配置中设置imageViewer的显示参数设置。该组件允许您定义切片参数用于指定三维数据的空间取向,并允许用户调节显示区域的尺寸、缩放比例因子以及定位参数等各项设置。

复制代码
    	auto imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
    	imageViewer->SetInputConnection(reader->GetOutputPort());
    
    	auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    	imageViewer->SetupInteractor(interactor);
    	imageViewer->SetSize(400, 400);
    	imageViewer->SetColorLevel(500);
    	imageViewer->SetColorWindow(1000);
    	imageViewer->SetSliceOrientationToXY(); // z-axis
    	imageViewer->GetRenderer()->SetBackground(1, 1, 1);

设置交互方式

复制代码
    	auto myStyle = vtkSmartPointer<myVtkInteractorStyleImage>::New();
    	myStyle->SetImageViewer(imageViewer);
    	interactor->SetInteractorStyle(myStyle);

自定义交互方式

该设置为默认模式;为实现通过鼠标滚轮操作切换切片的效果,我们进行了如下配置。

复制代码
    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);

效果

脑部CT图像

在这里插入图片描述

DisplayDICOMSeries. cxx

复制代码
    #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<vtkDICOMImageReader>::New();
    	reader->SetDirectoryName(argv[1]);
    	reader->Update();
    
    	auto imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
    	imageViewer->SetInputConnection(reader->GetOutputPort());
    
    	auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::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<myVtkInteractorStyleImage>::New();
    	myStyle->SetImageViewer(imageViewer);
    	interactor->SetInteractorStyle(myStyle);
    
    	imageViewer->Render();
    	imageViewer->GetRenderer()->ResetCamera();
    	imageViewer->Render();
    
    	interactor->Start();
    
    	return EXIT_SUCCESS;
    }

Example Download

Reference

VTKExamples/Cxx/IO/ReadDICOMSeries

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~