[VTK] About the series of functions of VTK images

I’m very happy to meet you in Xueyi’s CSDN, and give you Tangtang

Welcome to joinXueyi Community-CSDN Community Cloud

Foreword

This article summarizes the series of image functions in VTK, including image import (read), display, interaction and export (save). Detailed explanation of various solution ideas provided in VTK, friends can get it on demand!

Thank you all for your likes and follows. Xiaoyi will continue to work hard to share and make progress together!

Your likes are my motivation(^U^)ノ~YO

Table of Contents

Preface

1. Import (read) of images

2.vtkImageData analysis

3. Visualization of images (display of images)

window width window level

vtkImageViewer2

vtkImageActor

vtkImagePlaneWidget

4. Extraction of slice image data

in conclusion

If I could introduce VTK in one sentence, it would be an image and graphics library. VTK includes various processing of images. Let’s review them in detail today.

1. Image import (read)

source path: …VTK-9.*.*\IO\Image

Common two-dimensional images include PNG, JPG, BMP, etc. VTK provides interfaces for importing such images, such as

VTK: vtkPNGReader Class Reference,

VTK: vtkJPEGReader Class Reference

VTK: vtkBMPReader Class Reference

The dimensions of the imported image data mentioned above are (X, Y, 1), which can be directly assigned to the vtkImageActor object for display.

* Tip: If the dimensions of the image are (X, 1, Z) and are directly assigned to vtkImageActor, the Actor will be a line and the ideal image data cannot be displayed.

A common application field of VTK is medicine. When importing medical images such as CT images, mha, mhd images, etc., vtk also provides corresponding interfaces, such as VTK: vtkMetaImageReader Class Reference, VTK: vtkDICOMImageReader Class Reference

Example: Visualizing CT images

After reading the CT image data, you can use various visualization tools provided by VTK to visualize the image. For example, you can use vtkImageMapper3D to map image data into a 3D model. Here is sample code:

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageMapper3D.h>
#include <vtkImageData.h>

int main(int argc, char* argv[])
{
    //Read image data
    vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
    reader->SetDirectoryName("path/to/dicom/files"); // Set the DICOM file path
    reader->Update(); // Read DICOM file
    vtkSmartPointer<vtkImageData> imageData = reader->GetOutput(); // Get image data

    //Create renderer and visualization window
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(800, 800);

    // Map the image data into a 3D model and add it to the renderer
    vtkSmartPointer<vtkImageMapper3D> imageMapper = vtkSmartPointer<vtkImageMapper3D>::New();
    imageMapper->SetInputData(imageData);
    vtkSmartPointer<vtkActor> imageActor = vtkSmartPointer<vtkActor>::New();
    imageActor->SetMapper(imageMapper);
    renderer->AddActor(imageActor);

    //Start the visualization window
    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);
    renderWindow->Render();
    interactor->Start();

    return 0;
}

The above is a basic code example for reading CT images based on VTK, which can be modified and expanded according to actual needs.

2.vtkImageData analysis

The VTK image data structure consists of two parts: image header information and data. The image header information defines the basic information of the image, mainly including the starting point (Origin), pixel spacing (Spacing) and dimension (Dimension). Through these three parameters, the image space position and size can be determined.

Image data is the pixel value of the image pixel, which is generally represented and stored by a one-dimensional array. When the pixel index and image dimension are known, the pixel value corresponding to each pixel can be calculated. Generally speaking, the pixel range of grayscale images is 0~255, which can be represented by an unsigned char type. The grayscale range of medical image data is 0~65536, and the data type is unsigned short.

VTK provides multiple Source classes for creating images, located in VTK-9.*.*\Imaging\Sources. You can use this class to quickly create images.

Example: Create a VTK image

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

int main()
{
vtkSmartPointer<vtkImageData> img = vtkSmartPointer<vtkImageData>::New();
img->SetDimensions(16,16,1);
img->SetScalarTypeToUnsignedChar();
img->SetNumberOfScalarComponents(1);
img->AllocateScalars();

unsigned char *ptr = (unsigned char*)img->GetScalarPointer();
for(int i=0; i<16*16*1; i + + )
{
*ptr + + =i%6;
}

vtkSmartPointer<vtkImageActor> redActor =
vtkSmartPointer<vtkImageActor>::New();
redActor->SetInput(img);

double redViewport[4] = {0.0, 0.0, 1.0, 1.0};

vtkSmartPointer<vtkRenderer> redRenderer =
vtkSmartPointer<vtkRenderer>::New();
redRenderer->SetViewport(redViewport);
redRenderer->AddActor(redActor);
redRenderer->ResetCamera();
redRenderer->SetBackground(1.0, 1.0, 1.0);

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

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

renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();

return EXIT_SUCCESS;
}

3. Image visualization (image display)

Window width and window level

The window width is the grayscale range of the image display, and the window level is the center position of the window width. The window width only determines the range of the visible part of the grayscale range of the CT image, and the window level is also needed to determine the specific location of the visible grayscale range. For example, when the window width is 200 and the window level is 100, the visual range is 0~200; when the window level is 500, the visual range is 400~600.

vtkImageViewer2

The current VTK version uses vtkImageViewer2 for image display. vtkImageViewer2 encapsulates the visual rendering engine for image display, including objects such as vtkActor, vtkRenderer, vtkRenderWindow, vtkInteractorStyleImage, etc., to easily complete image display and interaction. Including image scaling, window width and window level adjustment, slice switching, etc.

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

//Test image: ../data/brain.mhd
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout<<argv[0]<<" "<<"ImageFile(*.mhd)"<<std::endl;
return EXIT_FAILURE;
}
vtkSmartPointer<vtkMetaImageReader> reader =
vtkSmartPointer<vtkMetaImageReader>::New();
reader->SetFileName(argv[1]);
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 EXIT_SUCCESS;
}

vtkImageActor

vtkImageActor is a three-dimensional image rendering Actor that maps the image to a polygon for display through texture mapping. Using vtkImageActor requires establishing a complete rendering pipeline including vtkImageActor, vtkRenderer, vtkRenderWindow, and vtkInteractorStyleImage.

Example

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

//Test image: ../data/lena.bmp
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout<<argv[0]<<" "<<"ImageFile(*.bmp)"<<std::endl;
return EXIT_FAILURE;
}
vtkSmartPointer<vtkBMPReader> reader =
vtkSmartPointer<vtkBMPReader>::New();
reader->SetFileName ( argv[1] );
reader->Update();

vtkSmartPointer<vtkImageActor> imgActor =
vtkSmartPointer<vtkImageActor>::New();
imgActor->SetInput(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 EXIT_SUCCESS;
}

Note: If the dimensions of the image are (X, 1, Z) and are directly assigned to vtkImageActor, the Actor will be a line and the ideal image data cannot be displayed.

Note 2: The pixel data type received by vtkImageActor must be unsigned char. If the type does not meet the requirements, it needs to be converted to an unsigned char type image in advance.

vtkImagePlaneWidget

vtkImagePlaneWidget uses vtkImageReslice to take out the slice data and map the slice image data to the corresponding Plane through texture mapping to display the image.

4. Extraction of slice image data

The vtkImageReslice class in vtk can extract image slices.

Example

#include <vtkSmartPointer.h>
#include <vtkMatrix4x4.h>
#include <vtkImageReslice.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkImageData.h>
#include <vtkMetaImageReader.h>
#include <vtkImageCast.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>

//Test image: ..\data\brain.mhd
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout<<argv[0]<<" "<<"ImageFile(*.mhd)"<<std::endl;
return EXIT_FAILURE;
}
vtkSmartPointer<vtkMetaImageReader> reader =
vtkSmartPointer<vtkMetaImageReader>::New();
reader->SetFileName(argv[1]);
reader->Update();

int extent[6];
double spacing[3];
double origin[3];

reader->GetOutput()->GetExtent(extent);
reader->GetOutput()->GetSpacing(spacing);
reader->GetOutput()->GetOrigin(origin);

double center[3];
center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);
center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);
center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);

static double axialElements[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};

vtkSmartPointer<vtkMatrix4x4> resliceAxes =
vtkSmartPointer<vtkMatrix4x4>::New();
resliceAxes->DeepCopy(axialElements);
resliceAxes->SetElement(0, 3, center[0]);
resliceAxes->SetElement(1, 3, center[1]);
resliceAxes->SetElement(2, 3, center[2]);

vtkSmartPointer<vtkImageReslice> reslice =
vtkSmartPointer<vtkImageReslice>::New();
reslice->SetInputConnection(reader->GetOutputPort());
reslice->SetOutputDimensionality(2);
reslice->SetResliceAxes(resliceAxes);
reslice->SetInterpolationModeToLinear();

vtkSmartPointer<vtkLookupTable> colorTable =
vtkSmartPointer<vtkLookupTable>::New();
colorTable->SetRange(0, 1000);
colorTable->SetValueRange(0.0, 1.0);
colorTable->SetSaturationRange(0.0, 0.0);
colorTable->SetRampToLinear();
colorTable->Build();

vtkSmartPointer<vtkImageMapToColors> colorMap =
vtkSmartPointer<vtkImageMapToColors>::New();
colorMap->SetLookupTable(colorTable);
colorMap->SetInputConnection(reslice->GetOutputPort());

vtkSmartPointer<vtkImageActor> imgActor =
vtkSmartPointer<vtkImageActor>::New();
imgActor->SetInput(colorMap->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->Render();
renderWindow->SetSize(640, 480);
renderWindow->SetWindowName("ImageResliceExample");

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

renderWindowInteractor->SetInteractorStyle(imagestyle);
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();

return EXIT_SUCCESS;
}

Conclusion:

This article mainly introduces the use of Image data in VTK and some insights. I hope it will be helpful to all my friends.

Thank you all for your likes and follows. Xiaoyi will continue to work hard to share and make progress together!

Your appreciation is my greatest motivation(^U^)ノ~YO

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Algorithm skill tree Home page Overview 57027 people are learning the system