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:
- Create a vtkNIFTIImageReader object for reading NIFTI image data.
- Get the dimension information of the image.
- Create three rendering windows (coronal, sagittal and axial views).
- Create three image viewers (viewer_coronal, viewer_sagittal, and viewer_axis) and associate them with the corresponding rendering windows.
- Set the interactor style.
- 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(); } } };