VTK+QT implementation, displaying three two-dimensional three-dimensional views of the three-dimensional model

The renderings are as follows:

This code uses QT and VTK libraries to display three three-dimensional views of the three-dimensional model on the interface. First, read the NIFTI image data through vtkNIFTIImageReader, and then create three rendering windows (coronal, sagittal, and axial views) to display images of the coronal, sagittal, and axial views respectively. Next, create three image viewers (viewer_coronal, viewer_sagittal, and viewer_axis) and associate them with the corresponding rendering windows. Finally, set the interactor style and start rendering.

Here are the main steps of the code:

  1. Create a vtkNIFTIImageReader object for reading NIFTI image data.
  2. Get the dimension information of the image.
  3. Create three rendering windows (coronal, sagittal and axial views).
  4. Create three image viewers (viewer_coronal, viewer_sagittal, and viewer_axis) and associate them with the corresponding rendering windows.
  5. Set the interactor style.
  6. Start rendering.

code show as below:

//Create a vtkNIFTIImageReader object for reading NIFTI image data
vtkSmartPointer<vtkNIFTIImageReader> reader =vtkSmartPointer<vtkNIFTIImageReader>::New();
                reader->SetDataByteOrderToLittleEndian(); // Set the data byte order to little endian
                reader->SetFileName(filePath.toUtf8().constData()); // Set the file path to be read
                reader->Update(); //Perform file reading operation

    int dims[3] = {};
    reader->GetOutput()->GetDimensions(dims);
    //Create a coronal rendering window
    vtkSmartPointer<vtkRenderer> ren_coronal = vtkSmartPointer<vtkRenderer>::New();
    vtkNew<vtkGenericOpenGLRenderWindow> win_coronal;
    ui.qvtkWidget_2->setRenderWindow(win_coronal.Get());
    win_coronal->AddRenderer(ren_coronal);

    //Create a sagittal rendering window
    vtkSmartPointer<vtkRenderer> ren_sagittal = vtkSmartPointer<vtkRenderer>::New();
    vtkNew<vtkGenericOpenGLRenderWindow> win_sagittal;
    ui.qvtkWidget_3->setRenderWindow(win_sagittal.Get());
    win_sagittal->AddRenderer(ren_sagittal);

    //Create an axis view rendering window
    vtkSmartPointer<vtkRenderer> ren_axis = vtkSmartPointer<vtkRenderer>::New();
    vtkNew<vtkGenericOpenGLRenderWindow> win_axis;
    ui.qvtkWidget_4->setRenderWindow(win_axis.Get());
    win_axis->AddRenderer(ren_axis);

    //Create a coronal image viewer
   vtkSmartPointer<vtkImageViewer2> viewer_coronal = vtkSmartPointer<vtkImageViewer2>::New();
    viewer_coronal->SetInputConnection(reader->GetOutputPort());
    viewer_coronal->SetRenderWindow(win_coronal);
    viewer_coronal->SetRenderer(ren_coronal);
    viewer_coronal->SetSliceOrientationToXZ();
    viewer_coronal->SetSlice(dims[1] / 2);

    //Create a sagittal image viewer
   vtkSmartPointer<vtkImageViewer2> viewer_sagittal = vtkSmartPointer<vtkImageViewer2>::New();
    viewer_sagittal->SetInputConnection(reader->GetOutputPort());
    viewer_sagittal->SetRenderWindow(win_sagittal);
    viewer_sagittal->SetRenderer(ren_sagittal);
    viewer_sagittal->SetSliceOrientationToYZ();
    viewer_sagittal->SetSlice(dims[0] / 2);

    //Create an axis view image viewer
    vtkSmartPointer<vtkImageViewer2> viewer_axis = vtkSmartPointer<vtkImageViewer2>::New();
    viewer_axis->SetInputConnection(reader->GetOutputPort());
    viewer_axis->SetRenderWindow(win_axis);
    viewer_axis->SetRenderer(ren_axis);
    viewer_axis->SetSliceOrientationToXY();
    viewer_axis->SetSlice(dims[2] / 2);

    //Add title text
    vtkSmartPointer<vtkTextActor> textActor_coronal = vtkSmartPointer<vtkTextActor>::New();
    textActor_coronal->SetTextScaleModeToNone();
    textActor_coronal->GetTextProperty()->SetFontSize(18);
    textActor_coronal->GetTextProperty()->SetFontFamilyToArial();
    textActor_coronal->SetInput("Coronal View");
    ren_coronal->AddActor2D(textActor_coronal);


    vtkSmartPointer<vtkTextActor> textActor_sagittal = vtkSmartPointer<vtkTextActor>::New();
    textActor_sagittal->SetTextScaleModeToNone();
    textActor_sagittal->GetTextProperty()->SetFontSize(18);
    textActor_sagittal->GetTextProperty()->SetFontFamilyToArial();
    textActor_sagittal->SetInput("Sagittal View");
    ren_sagittal->AddActor2D(textActor_sagittal);


    vtkSmartPointer<vtkTextActor> textActor_axis = vtkSmartPointer<vtkTextActor>::New();
    textActor_axis->SetTextScaleModeToNone();
    textActor_axis->GetTextProperty()->SetFontSize(18);
    textActor_axis->GetTextProperty()->SetFontFamilyToArial();
    textActor_axis->SetInput("Axis View");
    ren_axis->AddActor2D(textActor_axis);

    //Create a custom interactor style
    vtkSmartPointer<myVtkInteractorStyleImage> myInteractorStyle_coronal = vtkSmartPointer<myVtkInteractorStyleImage>::New();
    myInteractorStyle_coronal->SetImageViewer(viewer_coronal);

    vtkSmartPointer<myVtkInteractorStyleImage> myInteractorStyle_sagittal = vtkSmartPointer<myVtkInteractorStyleImage>::New();
    myInteractorStyle_sagittal->SetImageViewer(viewer_sagittal);

    vtkSmartPointer<myVtkInteractorStyleImage> myInteractorStyle_axis = vtkSmartPointer<myVtkInteractorStyleImage>::New();
    myInteractorStyle_axis->SetImageViewer(viewer_axis);


    //Create a rendering window interactor and set the interactor style
    vtkSmartPointer<vtkRenderWindowInteractor> renWin_coronal = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    viewer_coronal->SetupInteractor(renWin_coronal);
    renWin_coronal->SetInteractorStyle(myInteractorStyle_coronal);


    vtkSmartPointer<vtkRenderWindowInteractor> renWin_sagittal = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    viewer_sagittal->SetupInteractor(renWin_sagittal);
    renWin_sagittal->SetInteractorStyle(myInteractorStyle_sagittal);


    vtkSmartPointer<vtkRenderWindowInteractor> renWin_axis = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    viewer_axis->SetupInteractor(renWin_axis);
    renWin_axis->SetInteractorStyle(myInteractorStyle_axis);


    // Render the initial image and start the interactor
    viewer_coronal->Render();
    viewer_coronal->GetRenderer()->ResetCamera();
    win_coronal->Render();

    viewer_sagittal->Render();
    viewer_sagittal->GetRenderer()->ResetCamera();
    win_sagittal->Render();

    viewer_axis->Render();
    viewer_axis->GetRenderer()->ResetCamera();
    win_axis->Render();

Interactor code,

class myVtkInteractorStyleImage : public vtkInteractorStyleImage
{
public:
    static myVtkInteractorStyleImage* New();
    vtkTypeMacro(myVtkInteractorStyleImage, vtkInteractorStyleImage);
private:
    bool Active; // Flag indicating whether it is active

    int StartPosition[2];
    int EndPosition[2];

protected:
    vtkImageViewer2* _ImageViewer;
    int _Slice;
    int _MinSlice;
    int _MaxSlice;

public:
    void SetImageViewer(vtkImageViewer2* imageViwer)
    {
        _ImageViewer = imageViwer;
        _MinSlice = imageViwer->GetSliceMin();
        _MaxSlice = imageViwer->GetSliceMax();
        //Get the current slice data
        _Slice = imageViwer->GetSlice();
    }

protected:
    
    void MoveSliceForward()
    {
        
        if (_Slice < _MaxSlice)
        {
            _Slice + = 1;
            _ImageViewer->SetSlice(_Slice);
            _ImageViewer->Render();

        }
        
    }
    
    void MoveSliceBackward()
    {
        
        if (_Slice > _MinSlice)
        {
            _Slice -= 1;
            _ImageViewer->SetSlice(_Slice);
            _ImageViewer->Render();
        }
        
    }
    
    virtual void OnKeyDown()
    {
        QString key = this->GetInteractor()->GetKeySym();
        if (key.compare("Up") == 0)
        {
            MoveSliceForward();
        }
        else if (key.compare("Down") == 0)
        {
            MoveSliceBackward();
        }
        vtkInteractorStyleImage::OnKeyDown();
    }

    virtual void OnMouseWheelForward()
    {
        MoveSliceForward();
    }

    virtual void OnMouseWheelBackward()
    {
        if (_Slice > _MinSlice)
        {
            MoveSliceBackward();
        }
    }
    
};