[VTK Study Notes-07] VTK image display (vtkImageViewer2 displays two-dimensional images, vtkImageActor three-dimensional image rendering, vtkImageBlend image fusion)

Learning Tutorial: "Advanced VTK Graphics and Image Development" Zhang Xiaodong, Luo Huoling
Special thanks: Dongling Studio

5.2 VTK image display

5.2.1 vtkImageViewer2——Display two-dimensional images

Especially suitable for slice display of three-dimensional images

Example - Display a certain slice of a 3D medical image in *.mhd format
Source code:

#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;
}

operation result:
Insert image description here

5.2.2 vtkImageActor——3D image rendering

Texture mapping maps an image onto a polygon for display.
After using vtkBMPReader to read the image, create vtkImageActor, vtkRender, vtkRenderWindow, and vtkRenderWindowInteractor in sequence. You also need to define a vtkInteractorStyleImage object and assemble it into a rendering pipeline.
Source code:

#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;

}

operation result:
Insert image description here

Note: The pixel type of the image data vtkImageData received by vtkImageActor must be unsigned char. If the type does not meet the requirements, the image data type must be converted to unsigned char before displaying the image.

An error was encountered during compilation “vktSmartPointer”: 未声明的标识符. The solution turned out to be! ! Delete the error line in VS, rewrite the exact same line in notepad, and then paste it over and it will be ok. Amazing!

5.2.3 vtkImageBlend——Image fusion

Image fusion: Use the opacity of images to synthesize images. Use class vtkImageBlend to achieve image fusion. vtkImageBlend can accept multiple image inputs, and its output image is a fused image.

Two fusion modes: standard mode (default), blending mode
(1) standard mode
(2) blending mode.
The output results are normalized using opacity.

Example: Read in a grayscale image, generate a binary image, and fuse the image (the fusion of the grayscale image and the binary image). Finally three images are displayed within the window.
Source code:

#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;
}

operation result:
Insert image description here

Problem: Fusion image is not displayed
. Error message: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.

Reference for error correction: VTK Notes-Image Fusion-02-vtkImageBlend Class
Note: The VTK version is incompatible, which will cause SetInput() to be unusable.

  • If you want to establish a pipe connection, use SetInputConnection(), GetOutputPort()
  • If you want to process independent data sets, use SetInputData()

Guess you like

Origin blog.csdn.net/m0_51141265/article/details/132825554