VTK显示CT图像视图
在前面的基础上,显示一个常用的视图,读取CT扫描图像:
1 #include <vtkAutoInit.h> 2 VTK_MODULE_INIT(vtkRenderingOpenGL2); 3 VTK_MODULE_INIT(vtkInteractionStyle); 4 VTK_MODULE_INIT(vtkRenderingFreeType); 5 //VTK_MODULE_INIT(vtkRenderingVolumeOpenGL); 6 #include "vtkSmartPointer.h" 7 #include "vtkActor.h" 8 #include "vtkCamera.h" 9 #include "vtkCellPicker.h" 10 #include "vtkCommand.h" 11 #include "vtkImageActor.h" 12 #include "vtkImageReslice.h" 13 #include "vtkInteractorStyleImage.h" 14 #include "vtkImageMapToColors.h" 15 #include "vtkImagePlaneWidget.h" 16 #include "vtkImageReader.h" 17 #include "vtkInteractorEventRecorder.h" 18 #include "vtkLookupTable.h" 19 #include "vtkOutlineFilter.h" 20 #include "vtkDICOMImageReader.h" 21 #include "vtkPolyDataMapper.h" 22 #include "vtkProperty.h" 23 #include "vtkRenderWindow.h" 24 #include "vtkRenderWindowInteractor.h" 25 #include "vtkRenderer.h" 26 #include "vtkImageData.h" 27 #include "vtkPointData.h" 28 #include "vtkPlaneSource.h" 29 #include "vtkPlane.h" 30 #include "vtkResliceCursorActor.h" 31 #include "vtkResliceCursorPolyDataAlgorithm.h" 32 #include "vtkResliceCursor.h" 33 #include "vtkResliceCursorWidget.h" 34 #include "vtkResliceCursorLineRepresentation.h" 35 #include "vtkBiDimensionalWidget.h" 36 37 #include"vtkAxesActor.h" 38 #include"vtkTransform.h" 39 #include"vtkTextActor.h" 40 #include"vtkProperty2D.h" 41 42 43 44 class vtkResliceCursorCallback : public vtkCommand 45 { 46 public: 47 static vtkResliceCursorCallback *New() 48 { 49 return new vtkResliceCursorCallback; 50 } 51 void Execute(vtkObject *caller, unsigned long, void *callData) override 52 { 53 vtkImagePlaneWidget* ipw = dynamic_cast<vtkImagePlaneWidget*>(caller); 54 if (ipw) 55 { 56 double* wl = static_cast<double*>(callData); 57 58 if (ipw == this->IPW[0]) 59 { 60 this->IPW[1]->SetWindowLevel(wl[0], wl[1], 1); 61 this->IPW[2]->SetWindowLevel(wl[0], wl[1], 1); 62 } 63 else if (ipw == this->IPW[1]) 64 { 65 this->IPW[0]->SetWindowLevel(wl[0], wl[1], 1); 66 this->IPW[2]->SetWindowLevel(wl[0], wl[1], 1); 67 } 68 else if (ipw == this->IPW[2]) 69 { 70 this->IPW[0]->SetWindowLevel(wl[0], wl[1], 1); 71 this->IPW[1]->SetWindowLevel(wl[0], wl[1], 1); 72 } 73 } 74 vtkResliceCursorWidget *rcw = dynamic_cast<vtkResliceCursorWidget *>(caller); 75 if (rcw) 76 { 77 vtkResliceCursorLineRepresentation *rep = dynamic_cast<vtkResliceCursorLineRepresentation *>(rcw->GetRepresentation()); 78 vtkResliceCursor *rc = rep->GetResliceCursorActor()->GetCursorAlgorithm()->GetResliceCursor(); 79 for (int i = 0; i < 3; i++) 80 { 81 vtkPlaneSource *ps = static_cast<vtkPlaneSource *>(this->IPW[i]->GetPolyDataAlgorithm()); 82 ps->SetNormal(rc->GetPlane(i)->GetNormal()); 83 ps->SetCenter(rc->GetPlane(i)->GetOrigin()); 84 this->IPW[i]->UpdatePlacement(); 85 } 86 } 87 this->RCW[0]->Render(); 88 } 89 vtkResliceCursorCallback() {} 90 vtkImagePlaneWidget* IPW[3]; 91 vtkResliceCursorWidget *RCW[3]; 92 }; 93 94 int main() 95 { 96 vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New(); 97 reader->SetDirectoryName("H:/cv_code/vtk_code/test/CTdata/CT2"); 98 reader->Update(); 99 100 /*vtkSmartPointer<vtkOutlineFilter> outline = vtkSmartPointer<vtkOutlineFilter>::New(); 101 outline->SetInputConnection(reader->GetOutputPort());*/ 102 103 vtkSmartPointer<vtkPolyDataMapper> outlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); 104 outlineMapper->SetInputConnection(reader->GetOutputPort()); 105 106 vtkSmartPointer<vtkActor> outlineActor = vtkSmartPointer<vtkActor>::New(); 107 outlineActor->SetMapper(outlineMapper); 108 109 vtkSmartPointer<vtkRenderer> ren[4]; 110 vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New(); 111 renWin->SetMultiSamples(0); 112 113 for (int i = 0; i < 4; i++) 114 { 115 ren[i] = vtkSmartPointer<vtkRenderer>::New(); 116 renWin->AddRenderer(ren[i]); 117 } 118 119 vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New(); 120 iren->SetRenderWindow(renWin); 121 122 vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New(); 123 picker->SetTolerance(0.005); 124 125 vtkSmartPointer<vtkProperty> ipwProp = vtkSmartPointer<vtkProperty>::New(); 126 127 vtkSmartPointer<vtkImagePlaneWidget> planeWidget[3]; 128 int imageDims[3]; 129 reader->GetOutput()->GetDimensions(imageDims); 130 131 for (int i = 0; i < 3; i++) 132 { 133 planeWidget[i] = vtkSmartPointer<vtkImagePlaneWidget>::New(); 134 planeWidget[i]->SetInteractor(iren); 135 planeWidget[i]->SetPicker(picker); 136 planeWidget[i]->RestrictPlaneToVolumeOn(); 137 double color[3] = { 0, 0, 0 }; 138 color[i] = 1; 139 planeWidget[i]->GetPlaneProperty()->SetColor(color); 140 planeWidget[i]->SetTexturePlaneProperty(ipwProp); 141 planeWidget[i]->TextureInterpolateOff(); 142 planeWidget[i]->SetResliceInterpolateToLinear(); 143 planeWidget[i]->SetInputConnection(reader->GetOutputPort()); 144 planeWidget[i]->SetPlaneOrientation(i); 145 planeWidget[i]->SetSliceIndex(imageDims[i] / 2); 146 planeWidget[i]->DisplayTextOn(); 147 planeWidget[i]->SetDefaultRenderer(ren[3]); 148 planeWidget[i]->SetWindowLevel(1358, -27); 149 planeWidget[i]->On(); 150 planeWidget[i]->InteractionOn(); 151 } 152 153 planeWidget[1]->SetLookupTable(planeWidget[0]->GetLookupTable()); 154 planeWidget[2]->SetLookupTable(planeWidget[0]->GetLookupTable()); 155 156 vtkSmartPointer<vtkResliceCursorCallback> cbk = vtkSmartPointer<vtkResliceCursorCallback>::New(); 157 vtkSmartPointer< vtkResliceCursor > resliceCursor = vtkSmartPointer< vtkResliceCursor >::New(); 158 resliceCursor->SetCenter(reader->GetOutput()->GetCenter()); 159 resliceCursor->SetThickMode(0); 160 resliceCursor->SetThickness(10, 10, 10); 161 resliceCursor->SetImage(reader->GetOutput()); 162 163 vtkSmartPointer< vtkResliceCursorWidget > resliceCursorWidget[3]; 164 vtkSmartPointer< vtkResliceCursorLineRepresentation > resliceCursorRep[3]; 165 166 double viewUp[3][3] = { { 0, 0, -1 }, { 0, 0, 1 }, { 0, 1, 0 } }; 167 for (int i = 0; i < 3; i++) 168 { 169 resliceCursorWidget[i] = vtkSmartPointer< vtkResliceCursorWidget >::New(); 170 resliceCursorWidget[i]->SetInteractor(iren); 171 172 resliceCursorRep[i] = vtkSmartPointer< vtkResliceCursorLineRepresentation >::New(); 173 resliceCursorWidget[i]->SetRepresentation(resliceCursorRep[i]); 174 resliceCursorRep[i]->GetResliceCursorActor()->GetCursorAlgorithm()->SetResliceCursor(resliceCursor); 175 resliceCursorRep[i]->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(i); 176 177 const double minVal = reader->GetOutput()->GetScalarRange()[0]; 178 if (vtkImageReslice *reslice = vtkImageReslice::SafeDownCast(resliceCursorRep[i]->GetReslice())) 179 { 180 reslice->SetBackgroundColor(minVal, minVal, minVal, minVal); 181 } 182 183 resliceCursorWidget[i]->SetDefaultRenderer(ren[i]); 184 resliceCursorWidget[i]->SetEnabled(1); 185 186 ren[i]->GetActiveCamera()->SetFocalPoint(0, 0, 0); 187 double camPos[3] = { 0, 0, 0 }; 188 camPos[i] = 1; 189 ren[i]->GetActiveCamera()->SetPosition(camPos); 190 ren[i]->GetActiveCamera()->ParallelProjectionOn(); 191 ren[i]->GetActiveCamera()->SetViewUp(viewUp[i][0], viewUp[i][1], viewUp[i][2]); 192 ren[i]->ResetCamera(); 193 cbk->IPW[i] = planeWidget[i]; 194 cbk->RCW[i] = resliceCursorWidget[i]; 195 resliceCursorWidget[i]->AddObserver(vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk); 196 double range[2]; 197 reader->GetOutput()->GetScalarRange(range); 198 resliceCursorRep[i]->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0); 199 planeWidget[i]->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0); 200 resliceCursorRep[i]->SetLookupTable(resliceCursorRep[0]->GetLookupTable()); 201 planeWidget[i]->GetColorMap()->SetLookupTable(resliceCursorRep[0]->GetLookupTable()); 202 } 203 204 /*vtkSmartPointer<vtkTextActor> textActor = vtkSmartPointer<vtkTextActor>::New(); 205 textActor->SetInput("横断面"); 206 textActor->GetProperty()->SetColor(0.0,1.0,0.0);*/ 207 208 209 ren[0]->SetBackground(0.3, 0.1, 0.1); 210 ren[1]->SetBackground(0.1, 0.3, 0.1); 211 ren[2]->SetBackground(0.1, 0.1, 0.3); 212 ren[3]->AddActor(outlineActor); 213 ren[3]->SetBackground(0.1, 0.1, 0.1); 214 renWin->SetSize(600, 600); 215 216 ren[0]->SetViewport(0, 0, 0.5, 0.5); 217 ren[1]->SetViewport(0.5, 0, 1, 0.5); 218 ren[2]->SetViewport(0, 0.5, 0.5, 1); 219 ren[3]->SetViewport(0.5, 0.5, 1, 1); 220 renWin->Render(); 221 222 ren[3]->GetActiveCamera()->Elevation(110); 223 ren[3]->GetActiveCamera()->SetViewUp(0, 0, -1); 224 ren[3]->GetActiveCamera()->Azimuth(45); 225 ren[3]->GetActiveCamera()->Dolly(1.15); 226 ren[3]->ResetCameraClippingRange(); 227 228 vtkSmartPointer< vtkInteractorStyleImage > style = vtkSmartPointer< vtkInteractorStyleImage >::New(); 229 iren->SetInteractorStyle(style); 230 iren->Initialize(); 231 iren->Start(); 232 return EXIT_SUCCESS; 233 }