【VTK学习笔记-07】VTK图像显示(vtkImageViewer2显示二维图像、vtkImageActor三维图像渲染、vtkImageBlend图像融合)

学习教程:《VTK图形图像开发进阶》张晓东,罗火灵
特别感谢:东灵工作室

5.2 VTK图像显示

5.2.1 vtkImageViewer2——显示二维图像

尤其适合三维图像的切片展示

示例——显示一个*.mhd格式的三维医学图像的某个切片
源码:

#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkMetaImageReader.h>

//测试图像:../data/brain.mhd  
int main()
{
	//使用vtkMetaImageReader读入一个*.mhd格式的图像
	vtkSmartPointer<vtkMetaImageReader>reader = vtkSmartPointer<vtkMetaImageReader>::New();
	reader->SetFileName("../data/brain.mhd");
	reader->Update();

	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(40);//切片索引
	imageViewer->SetSliceOrientationToXY();//切片方向
	imageViewer->Render();

	imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
	imageViewer->SetSize(640, 480);
	imageViewer->GetRenderWindow()->SetWindowName("DisplayImageExample");

	renderWindowInteractor->Start();

	return 0;
}

运行结果:
在这里插入图片描述

5.2.2 vtkImageActor——三维图像渲染

通过纹理映射将图像映射到一个多边形上进行显示。
使用vtkBMPReader读入图像后,依次建立vtkImageActor、vtkRender、vtkRenderWindow、vtkRenderWindowInteractor。还需定义一个vtkInteractorStyleImage对象,组装为渲染管线。
源码:

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkBMPReader.h>
#include <vtkImageActor.h>


//测试图像:../data/lena.bmp
int main()
{
	//读取图片
	vtkSmartPointer<vtkBMPReader>reader = vtkSmartPointer<vtkBMPReader>::New();
	reader->SetFileName("../data/lena.bmp");
	reader->Update();

	//渲染管线
	vtkSmartPointer<vtkImageActor>imgActor = vtkSmartPointer<vtkImageActor>::New();
	imgActor->SetInputData(reader->GetOutput());

	vtkSmartPointer<vtkRenderer>renderer = vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor(imgActor);
	renderer->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderWindow>renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
	renderWindow->SetSize(640, 480);
	renderWindow->Render();
	renderWindow->SetWindowName("DisplayImageExample2");

	vtkSmartPointer<vtkRenderWindowInteractor>renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();

	renderWindowInteractor->SetInteractorStyle(style);
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();

	renderWindowInteractor->Start();

	return 0;

}

运行结果:
在这里插入图片描述

注意:vtkImageActor接收的图像数据vtkImageData像素类型必须为unsigned char,如果类型不符合要求,在显示图像前需先将图像数据类型转换为unsigned char。

在编译过程中遇到了“vktSmartPointer”: 未声明的标识符错误。解决的办法竟然是!!把vs里报错这行删掉,在记事本里重写了一行一模一样的,然后再粘贴过来就ok了。Amazing!

5.2.3 vtkImageBlend——图像融合

图像融合:利用图像的不透明度来合成图像。使用类vtkImageBlend实现图像的融合。vtkImageBlend可以接受多个图像输入,其输出图像为融合图像。

两种融合模式:标准模式(默认)、混合模式
(1)标准模式
(2)混合模式
输出结果利用不透明度和做归一化。

示例:读入一幅灰度图像,另外生成一个二值图像,和融合图像(灰度图像与二值图像的融合)。最终在窗口内显示三张图像。
源码:

#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkImageBlend.h>
#include <vtkJPEGReader.h>
#include <vtkImageActor.h>
#include <vtkImageCast.h>

//测试图像:../data/lena-gray.jpg
int main()
{
	//读入灰度图像      
	vtkSmartPointer<vtkJPEGReader>reader = vtkSmartPointer<vtkJPEGReader>::New();
	reader->SetFileName("../data/lena-gray.jpg");
	reader->Update();

	//生成二值图像      
	vtkSmartPointer<vtkImageCanvasSource2D>imageSource = vtkSmartPointer<vtkImageCanvasSource2D>::New();
	imageSource->SetNumberOfScalarComponents(1);
	imageSource->SetScalarTypeToUnsignedChar();
	imageSource->SetExtent(0, 512, 0, 512, 0, 0);
	imageSource->SetDrawColor(0.0);
	imageSource->FillBox(0, 512, 0, 512);
	imageSource->SetDrawColor(255.0);
	imageSource->FillBox(100,400,100,400);
	imageSource->Update();

	//融合图像:两个输入(0:灰度图像;1:二值图像)
	vtkSmartPointer<vtkImageBlend>imageBlend = vtkSmartPointer<vtkImageBlend>::New();
	//imageBlend->SetInputData(0, (vtkDataObject*)reader->GetOutput());
	//imageBlend->SetInputData(1, (vtkDataObject*)imageSource->GetOutput()); // 这样写不能显示融合图像
	imageBlend->AddInputData(reader->GetOutput());
	imageBlend->AddInputData(imageSource->GetOutput()); //修改为Add,然后取消编号就ok
	imageBlend->SetOpacity(0, 0.4);
	imageBlend->SetOpacity(1, 0.6);  //用于设置对应id号的图像不透明度的大小
	imageBlend->Update();

	//显示三组图像
	//(1)创建actors
	vtkSmartPointer<vtkImageActor>originalActor1 = vtkSmartPointer<vtkImageActor>::New();
	originalActor1->SetInputData(reader->GetOutput());

	vtkSmartPointer<vtkImageActor>originalActor2 = vtkSmartPointer<vtkImageActor>::New();
	originalActor2->SetInputData(imageSource->GetOutput());

	vtkSmartPointer<vtkImageActor>blendActor = vtkSmartPointer<vtkImageActor>::New();
	blendActor->SetInputData(imageBlend->GetOutput());

	//(2)定义viewport范围 (xmin,ymin,xmax,ymax)
	double leftViewport[4] = { 0.0,0.0,0.33,1.0 };
	double midViewport[4] = { 0.33,0.0,0.66,1.0 };
	double rightViewport[4] = { 0.66,0.0,1.0,1.0 };

	//(3)创建渲染示例renderers
	vtkSmartPointer<vtkRenderer>originalRenderer1 = vtkSmartPointer<vtkRenderer>::New();
	originalRenderer1->SetViewport(leftViewport);
	originalRenderer1->AddActor(originalActor1);
	originalRenderer1->ResetCamera();
	originalRenderer1->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderer>originalRenderer2 = vtkSmartPointer<vtkRenderer>::New();
	originalRenderer2->SetViewport(midViewport);
	originalRenderer2->AddActor(originalActor2);
	originalRenderer2->ResetCamera();
	originalRenderer2->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderer>blendRenderer = vtkSmartPointer<vtkRenderer>::New();
	blendRenderer->SetViewport(rightViewport);
	blendRenderer->AddActor(blendActor);
	blendRenderer->ResetCamera();
	blendRenderer->SetBackground(1.0, 1.0, 1.0);

	//(4)创建渲染窗口renderWindow
	vtkSmartPointer<vtkRenderWindow>renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(originalRenderer1);
	renderWindow->AddRenderer(originalRenderer2);
	renderWindow->AddRenderer(blendRenderer);
	renderWindow->SetSize(640, 320);
	renderWindow->Render();
	renderWindow->SetWindowName("ImageBlendExample");

	//(5)创建交互RenderWindowInteractor以及交互样式
	vtkSmartPointer<vtkRenderWindowInteractor>renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
	renderWindowInteractor->SetInteractorStyle(style);
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();

	return 0;
}

运行结果:
在这里插入图片描述

问题:不显示融合图像
报错信息:vtkCompositeDataPipeline (00000201D3E32960): Input for connection index 0 on input port index 1 for algorithm vtkImageBlend(00000201D3E1F930) is of type vtkImageData, but a vtkImageStencilData is required.

纠错参考:VTK笔记-图像融合-02-vtkImageBlend类
注意:VTK版本不兼容,会导致SetInput()无法使用。

  • 如果要建立管道连接,使用SetInputConnection(),GetOutputPort()
  • 如果要处理独立数据集,使用SetInputData()
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值