VTK笔记-图像相关-vtkImageViewer2类

vtkImageViewer2

  vtkImageViewer2类用来显示二维图像;vtk的版本更新,使用vtkImageViewer2替代vtkImageViewer类;
  vtkImageViewer2封装了VTK图像显示的可视化渲染引擎,包括vtkActor、vtkRender、vtkRenderWindow、vtkInteractorStyleImage等对象,可以方便地完成图像显示和交互,还提供了图像缩放、窗宽窗位调节,并提供切片选择以及切片方向设置的接口,尤其适合三维图像的切片显示;
在这里插入图片描述

一、vtkImageViewer2类成员

1.1 成员变量

  vtkImageViewer2中封装的渲染引擎的对象有如下几个:

vtkImageMapToWindowLevelColors* WindowLevel;
vtkRenderWindow* RenderWindow;
vtkRenderer* Renderer;
vtkImageActor* ImageActor;
vtkRenderWindowInteractor* Interactor;
vtkInteractorStyleImage* InteractorStyle;

1.2 对外接口

  设置输入数据来源:

virtual void SetInputData(vtkImageData* in);   
virtual void SetInputConnection(vtkAlgorithmOutput* input);

  设置切图显示方向:

virtual void SetSliceOrientation(int orientation);
virtual void SetSliceOrientationToXY(); 
virtual void SetSliceOrientationToYZ();  
virtual void SetSliceOrientationToXZ();

  SetSliceOrientation中的三个参数分别为:

枚举名称枚举值含义
SLICE_ORIENTATION_YZ0垂直于YZ面,X轴方向
SLICE_ORIENTATION_XZ1垂直于XZ面,Y轴方向
SLICE_ORIENTATION_XY2垂直于XY面,Z轴方向

    默认情况下,切片的方向是垂直与XY平面,沿着Z轴方向;
  SetSliceOrientationToXY、SetSliceOrientationToYZ、SetSliceOrientationToXZ分别调用了不同参数的SetSliceOrientation;
  设置当前显示方向上的当前切片索引:

virtual void SetSlice(int s);

  int s的输入范围在对于显示方向的切片范围内,一般从0开始到切片个数-1;
  获取当前显示方向上的切片索引范围:

virtual int GetSliceMin();
virtual int GetSliceMax();
virtual void GetSliceRange(int range[2]) { this->GetSliceRange(range[0], range[1]); }
virtual void GetSliceRange(int& min, int& max);
virtual int* GetSliceRange();

  窗宽窗位相关:
  根据设定的窗宽窗位把数值映射到颜色上;

virtual double GetColorWindow();
virtual double GetColorLevel();
virtual void SetColorWindow(double s);
virtual void SetColorLevel(double s);

  注意:设定不同的窗宽和窗位,可能会出现不一样的显示效果,可能会将彩色图显示为灰度图;
  图像尺寸和坐标:

virtual int* GetPosition() VTK_SIZEHINT(2);
virtual void SetPosition(int x, int y);
virtual void SetPosition(int a[2]) { this->SetPosition(a[0], a[1]); }
virtual int* GetSize() VTK_SIZEHINT(2);  
virtual void SetSize(int width, int height);
virtual void SetSize(int a[2]) { this->SetSize(a[0], a[1]); }

  设置渲染引擎相关:

virtual void SetRenderWindow(vtkRenderWindow* arg);
virtual void SetRenderer(vtkRenderer* arg);  
virtual void SetupInteractor(vtkRenderWindowInteractor*);

  使用vtkImageViewer2中的vtkImageActor等对象对图像,对相机等信息进行控制改变;
  例如,对vtkImageViewer2内的图像进行旋转180°操作;

vtkNew<vtkTransform> transform;
transform->RotateZ(180);
vtkNew<vtkImageViewer2> imageViewer;		
imageViewer->GetImageActor()->SetUserTransform(transform);

二、实例

2.1 具体使用步骤

使用SetInputConnection设置输入数据来源;
使用SetupInteractor设置交互器,用来实现鼠标、键盘消息响应;
使用SetColorLevel设置窗位;
使用SetColorWindow设置窗宽;
使用SetSliceOrientationToXY设置切片显示方向;
使用SetSlice当前显示切片索引;
渲染Render;

2.2 完整代码

#include "vtkStringArray.h"
#include "vtkJPEGReader.h"
#include "vtkImageViewer2.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);

using namespace std;
int main()
{
	vtkSmartPointer<vtkStringArray> fileArray = vtkSmartPointer<vtkStringArray>::New();
	char fileName[128] = { 0 };

	for (size_t i = 0; i < 100; i++)
	{
		memset(fileName, 0, 128);
		sprintf(fileName, "./data/Head/head%03d.jpg", i);
		// vtkstd::string fileStr(fileName);
		// vtkstd在VTK7版本中不再使用,用std替代
		fileArray->InsertNextValue(fileName);
	}

	// 读取JPG序列图像
	vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();
	reader->SetFileNames(fileArray);

	// 显示读取的JPG图像
	vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
	imageViewer->SetInputConnection(reader->GetOutputPort());
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();	
	imageViewer->SetupInteractor(renderWindowInteractor);
	imageViewer->SetColorLevel(500);
	imageViewer->SetColorWindow(2000);
	imageViewer->SetSlice(50);
	imageViewer->SetSliceOrientationToXY();
	imageViewer->Render();

	renderWindowInteractor->Start();
	return 0;
}

三、相关知识

3.1窗宽窗位

  窗宽是图像显示的灰度范围。一般显示器的灰度范围为256级,医学图像的灰度范围远远大于这个范围,所以显示器不足以显示所有的灰度级,需要使用窗宽来定义想要显示的灰度范围;
  一般情况下,可以将灰度值高于窗宽范围的最大值时,将像素值显示为白色值(255);将灰度值低于窗宽范围的最小值时,将像素值显示为黑色值(0);增大窗宽范围,可以显示更多不同灰度组织结构,但会减低组织之间的对比度;减小窗宽范围,可以减少所显示不同灰度组织结构,也就增大了组织结构之间的对比度;
  窗位时窗宽的中心位置;窗宽只是确定了像素上的可视化的范围,是一个具体值,单独依靠窗宽不能确定这个范围的上限是多少和下限是多少,需要配合使用窗位来确定;比如上一代码中:窗宽为2000,只能说明窗宽的范围是2000,不能说明是从0到2000,还是-1000到1000,设置窗位为500时,窗宽2000,就能表示可视灰度范围为-500到1500; 在这里插入图片描述
  手动进行像素换算灰度值时,可以参照上图。

void ConvertDigitImageToGrayImageByWindowLevelAndWindowWidth(short* digitImage, short* grayImage, int size, int window_level, int window_width){
	double rate = 256.0 / window_width;
	for (size_t i = 0; i < size; i++){
		int tmp = 128.0 + (grayImage[i] - window_level)*rate;
		if (tmp < 0){
			tmp = 0;
		}
		else if (tmp > 255)	{
			tmp = 255;
		}
		digitImage[i] = tmp;
	}
}

读彩色bmp图像

  读取一张雷娜的彩色bmp图像;

vtkNew<vtkBMPReader> bmp_reader;
bmp_reader->SetFileName("G:\\Data\\lena.bmp");
bmp_reader->Update();		

vtkNew<vtkImageViewer2> imageViewer;
imageViewer->SetInputData(bmp_reader->GetOutput());		
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->SetColorLevel(500);
imageViewer->SetColorWindow(2000);
imageViewer->Render();
renderWindowInteractor->Start();

  显示效果
在这里插入图片描述

vtkNew<vtkBMPReader> bmp_reader;
bmp_reader->SetFileName("G:\\Data\\lena.bmp");
bmp_reader->Update();		

vtkNew<vtkImageViewer2> imageViewer;
imageViewer->SetInputData(bmp_reader->GetOutput());		
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->SetColorWindow(255.0);
imageViewer->SetColorLevel(127.5);
imageViewer->Render();
renderWindowInteractor->Start();

在这里插入图片描述
  vtkImageViewer2内部使用一个vtkWindowLevelLookupTable类型的成员变量,用于将图像数值转换为颜色值RGB或者RGBA值;

3.2医学图像二维视图

上文中设置切片方向是通过不同的方向来观察人体内部组织结构;
  医学图像中,不同方向的切面都有特定的名字;
  XY面:横断面(Transverse/Axial Plane),是指身体与地面平行的切面;
  XZ面:冠状面(Coronal Plane),是沿着身体左右径所作的与地面垂直的切面,也可以看作是从左胳膊到右胳膊为行,以从头到脚为列,生成的切面;
  YZ面:矢状面(Sagital Plane),是沿着身体的前后径所作的与地面垂直的切面,也可以看作是从后背到前胸为行,以从头到脚为列,生成的切面;
在这里插入图片描述

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑山老妖的笔记本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值