VTK FixedPointVolumeRayCastMapperCT 体渲染


 1 #include <vtkFixedPointVolumeRayCastMapper.h>
 2 
 3 #include <vtkBoxWidget.h>
 4 #include <vtkCamera.h>
 5 #include <vtkCommand.h>
 6 #include <vtkColorTransferFunction.h>
 7 #include <vtkDICOMImageReader.h>
 8 #include <vtkImageData.h>
 9 #include <vtkImageResample.h>
 10 #include <vtkMetaImageReader.h>
 11 #include <vtkPiecewiseFunction.h>
 12 #include <vtkPlanes.h>
 13 #include <vtkProperty.h>
 14 #include <vtkRenderer.h>
 15 #include <vtkRenderWindow.h>
 16 #include <vtkRenderWindowInteractor.h>
 17 #include <vtkVolume.h>
 18 #include <vtkVolumeProperty.h>
 19 #include <vtkXMLImageDataReader.h>
 20 #include <vtkNamedColors.h>
 21 
 22 #define VTI_FILETYPE 1
 23 #define MHA_FILETYPE 2
 24 
 25 namespace
 26 {  27     void PrintUsage()  28  {  29         cout << "Usage: " << endl;  30         cout << endl;  31         cout << " FixedPointVolumeRayCastMapperCT <options>" << endl;  32         cout << endl;  33         cout << "where options may include: " << endl;  34         cout << endl;  35         cout << " -DICOM <directory>" << endl;  36         cout << " -VTI <filename>" << endl;  37         cout << " -MHA <filename>" << endl;  38         cout << " -DependentComponents" << endl;  39         cout << " -Clip" << endl;  40         cout << " -MIP <window> <level>" << endl;  41         cout << " -CompositeRamp <window> <level>" << endl;  42         cout << " -CompositeShadeRamp <window> <level>" << endl;  43         cout << " -CT_Skin" << endl;  44         cout << " -CT_Bone" << endl;  45         cout << " -CT_Muscle" << endl;  46         cout << " -FrameRate <rate>" << endl;  47         cout << " -DataReduction <factor>" << endl;  48         cout << endl;  49         cout << "You must use either the -DICOM option to specify the directory where" << endl;  50         cout << "the data is located or the -VTI or -MHA option to specify the path of a .vti file." << endl;  51         cout << endl;  52         cout << "By default, the program assumes that the file has independent components," << endl;  53         cout << "use -DependentComponents to specify that the file has dependent components." << endl;  54         cout << endl;  55         cout << "Use the -Clip option to display a cube widget for clipping the volume." << endl;  56         cout << "Use the -FrameRate option with a desired frame rate (in frames per second)" << endl;  57         cout << "which will control the interactive rendering rate." << endl;  58         cout << "Use the -DataReduction option with a reduction factor (greater than zero and" << endl;  59         cout << "less than one) to reduce the data before rendering." << endl;  60         cout << "Use one of the remaining options to specify the blend function" << endl;  61         cout << "and transfer functions. The -MIP option utilizes a maximum intensity" << endl;  62         cout << "projection method, while the others utilize compositing. The" << endl;  63         cout << "-CompositeRamp option is unshaded compositing, while the other" << endl;  64         cout << "compositing options employ shading." << endl;  65         cout << endl;  66         cout << "Note: MIP, CompositeRamp, CompositeShadeRamp, CT_Skin, CT_Bone," << endl;  67         cout << "and CT_Muscle are appropriate for DICOM data. MIP, CompositeRamp," << endl;  68         cout << "and RGB_Composite are appropriate for RGB data." << endl;  69         cout << endl;  70         cout << "Example: FixedPointVolumeRayCastMapperCT -DICOM CTNeck -MIP 4096 1024" << endl;  71         cout << endl;  72  }  73 }  74 int main(int argc, char* argv[])  75 {  76     // Parse the parameters
 77 
 78     int count = 1;  79     char* dirname = NULL;  80     double opacityWindow = 4096;  81     double opacityLevel = 2048;  82     int blendType = 6;  83     int clip = 0;  84     double reductionFactor = 1.0;  85     double frameRate = 10.0;  86     //char* dirname = "E:\\工作\\DICOM";
 87     int fileType = 0;  88 
 89     bool independentComponents = true;  90 
 91      
 92 
 93     // Create the renderer, render window and interactor
 94     vtkSmartPointer<vtkNamedColors> colors =
 95         vtkSmartPointer<vtkNamedColors>::New();  96     vtkSmartPointer<vtkRenderer> renderer =
 97         vtkSmartPointer<vtkRenderer>::New();  98     vtkSmartPointer<vtkRenderWindow> renWin =
 99         vtkSmartPointer<vtkRenderWindow>::New(); 100     renWin->AddRenderer(renderer); 101 
102     // Connect it all. Note that funny arithematic on the 103     // SetDesiredUpdateRate - the vtkRenderWindow divides it 104     // allocated time across all renderers, and the renderer 105     // divides it time across all props. If clip is 106     // true then there are two props
107     vtkSmartPointer<vtkRenderWindowInteractor> iren =
108         vtkSmartPointer<vtkRenderWindowInteractor>::New(); 109     iren->SetRenderWindow(renWin); 110     iren->SetDesiredUpdateRate(frameRate / (1 + clip)); 111 
112     iren->GetInteractorStyle()->SetDefaultRenderer(renderer); 113 
114     // Read the data
115     vtkSmartPointer<vtkAlgorithm> reader =
116         vtkSmartPointer<vtkAlgorithm>::New(); 117     vtkSmartPointer<vtkImageData> input =
118         vtkSmartPointer<vtkImageData>::New(); 119     /*if (dirname) 120  {*/
121         vtkSmartPointer<vtkDICOMImageReader> dicomReader =
122             vtkSmartPointer<vtkDICOMImageReader>::New(); 123         dicomReader->SetDirectoryName("E:\\工作\\DICOM"); 124         dicomReader->Update(); 125         input = dicomReader->GetOutput(); 126         reader = dicomReader; 127    /* }*/
128    /* else if (fileType == VTI_FILETYPE) 129  { 130  vtkSmartPointer<vtkXMLImageDataReader> xmlReader = 131  vtkSmartPointer<vtkXMLImageDataReader>::New(); 132  xmlReader->SetFileName(fileName); 133  xmlReader->Update(); 134  input = xmlReader->GetOutput(); 135  reader = xmlReader; 136  } 137  else if (fileType == MHA_FILETYPE) 138  { 139  vtkSmartPointer<vtkMetaImageReader> metaReader = 140  vtkSmartPointer<vtkMetaImageReader>::New(); 141  metaReader->SetFileName(fileName); 142  metaReader->Update(); 143  input = metaReader->GetOutput(); 144  reader = metaReader; 145  } 146  else 147  { 148  cout << "Error! Not VTI or MHA!" << endl; 149  exit(EXIT_FAILURE); 150  }*/
151 
152     // Verify that we actually have a volume
153     int dim[3]; 154     input->GetDimensions(dim); 155 
156     if (dim[0] < 2 ||
157         dim[1] < 2 ||
158         dim[2] < 2) 159  { 160         cout << "Error loading data!" << endl; 161  exit(EXIT_FAILURE); 162  } 163 
164     vtkSmartPointer<vtkImageResample> resample =
165         vtkSmartPointer<vtkImageResample>::New(); 166     if (reductionFactor < 1.0) 167  { 168         resample->SetInputConnection(reader->GetOutputPort()); 169         resample->SetAxisMagnificationFactor(0, reductionFactor); 170         resample->SetAxisMagnificationFactor(1, reductionFactor); 171         resample->SetAxisMagnificationFactor(2, reductionFactor); 172  } 173 
174     // Create our volume and mapper
175     vtkSmartPointer<vtkVolume> volume =
176         vtkSmartPointer<vtkVolume>::New(); 177     vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> mapper =
178         vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New(); 179 
180     if (reductionFactor < 1.0) 181  { 182         mapper->SetInputConnection(resample->GetOutputPort()); 183  } 184     else
185  { 186         mapper->SetInputConnection(reader->GetOutputPort()); 187  } 188 
189 
190     // Set the sample distance on the ray to be 1/2 the average spacing
191     double spacing[3]; 192     if (reductionFactor < 1.0) 193  { 194         resample->GetOutput()->GetSpacing(spacing); 195  } 196     else
197  { 198         input->GetSpacing(spacing); 199  } 200 
201     // mapper->SetSampleDistance( (spacing[0]+spacing[1]+spacing[2])/6.0 ); 202     // mapper->SetMaximumImageSampleDistance(10.0); 203 
204 
205       // Create our transfer function
206     vtkSmartPointer<vtkColorTransferFunction> colorFun =
207         vtkSmartPointer<vtkColorTransferFunction>::New(); 208     vtkSmartPointer<vtkPiecewiseFunction> opacityFun =
209         vtkSmartPointer<vtkPiecewiseFunction>::New(); 210     // Create the property and attach the transfer functions
211     vtkSmartPointer<vtkVolumeProperty> property =
212         vtkSmartPointer<vtkVolumeProperty>::New(); 213     property->SetIndependentComponents(independentComponents); 214     property->SetColor(colorFun); 215     property->SetScalarOpacity(opacityFun); 216     property->SetInterpolationTypeToLinear(); 217 
218     // connect up the volume to the property and the mapper
219     volume->SetProperty(property); 220     volume->SetMapper(mapper); 221 
222     // Depending on the blend type selected as a command line option, 223     // adjust the transfer function
224     switch (blendType) 225  { 226         // MIP 227         // Create an opacity ramp from the window and level values. 228         // Color is white. Blending is MIP.
229     case 0: 230         colorFun->AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0); 231         opacityFun->AddSegment(opacityLevel - 0.5 * opacityWindow, 0.0, 232             opacityLevel + 0.5 * opacityWindow, 1.0); 233         mapper->SetBlendModeToMaximumIntensity(); 234         break; 235 
236         // CompositeRamp 237         // Create a ramp from the window and level values. Use compositing 238         // without shading. Color is a ramp from black to white.
239     case 1: 240         colorFun->AddRGBSegment(opacityLevel - 0.5 * opacityWindow, 0.0, 0.0, 0.0, 241             opacityLevel + 0.5 * opacityWindow, 1.0, 1.0, 1.0); 242         opacityFun->AddSegment(opacityLevel - 0.5 * opacityWindow, 0.0, 243             opacityLevel + 0.5 * opacityWindow, 1.0); 244         mapper->SetBlendModeToComposite(); 245         property->ShadeOff(); 246         break; 247 
248         // CompositeShadeRamp 249         // Create a ramp from the window and level values. Use compositing 250         // with shading. Color is white.
251     case 2: 252         colorFun->AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0); 253         opacityFun->AddSegment(opacityLevel - 0.5 * opacityWindow, 0.0, 254             opacityLevel + 0.5 * opacityWindow, 1.0); 255         mapper->SetBlendModeToComposite(); 256         property->ShadeOn(); 257         break; 258 
259         // CT_Skin 260         // Use compositing and functions set to highlight skin in CT data 261         // Not for use on RGB data
262     case 3: 263         colorFun->AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0); 264         colorFun->AddRGBPoint(-1000, .62, .36, .18, 0.5, 0.0); 265         colorFun->AddRGBPoint(-500, .88, .60, .29, 0.33, 0.45); 266         colorFun->AddRGBPoint(3071, .83, .66, 1, 0.5, 0.0); 267 
268         opacityFun->AddPoint(-3024, 0, 0.5, 0.0); 269         opacityFun->AddPoint(-1000, 0, 0.5, 0.0); 270         opacityFun->AddPoint(-500, 1.0, 0.33, 0.45); 271         opacityFun->AddPoint(3071, 1.0, 0.5, 0.0); 272 
273         mapper->SetBlendModeToComposite(); 274         property->ShadeOn(); 275         property->SetAmbient(0.1); 276         property->SetDiffuse(0.9); 277         property->SetSpecular(0.2); 278         property->SetSpecularPower(10.0); 279         property->SetScalarOpacityUnitDistance(0.8919); 280         break; 281 
282         // CT_Bone 283         // Use compositing and functions set to highlight bone in CT data 284         // Not for use on RGB data
285     case 4: 286         colorFun->AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0); 287         colorFun->AddRGBPoint(-16, 0.73, 0.25, 0.30, 0.49, .61); 288         colorFun->AddRGBPoint(641, .90, .82, .56, .5, 0.0); 289         colorFun->AddRGBPoint(3071, 1, 1, 1, .5, 0.0); 290 
291         opacityFun->AddPoint(-3024, 0, 0.5, 0.0); 292         opacityFun->AddPoint(-16, 0, .49, .61); 293         opacityFun->AddPoint(641, .72, .5, 0.0); 294         opacityFun->AddPoint(3071, .71, 0.5, 0.0); 295 
296         mapper->SetBlendModeToComposite(); 297         property->ShadeOn(); 298         property->SetAmbient(0.1); 299         property->SetDiffuse(0.9); 300         property->SetSpecular(0.2); 301         property->SetSpecularPower(10.0); 302         property->SetScalarOpacityUnitDistance(0.8919); 303         break; 304 
305         // CT_Muscle 306         // Use compositing and functions set to highlight muscle in CT data 307         // Not for use on RGB data
308     case 5: 309         colorFun->AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0); 310         colorFun->AddRGBPoint(-155, .55, .25, .15, 0.5, .92); 311         colorFun->AddRGBPoint(217, .88, .60, .29, 0.33, 0.45); 312         colorFun->AddRGBPoint(420, 1, .94, .95, 0.5, 0.0); 313         colorFun->AddRGBPoint(3071, .83, .66, 1, 0.5, 0.0); 314 
315         opacityFun->AddPoint(-3024, 0, 0.5, 0.0); 316         opacityFun->AddPoint(-155, 0, 0.5, 0.92); 317         opacityFun->AddPoint(217, .68, 0.33, 0.45); 318         opacityFun->AddPoint(420, .83, 0.5, 0.0); 319         opacityFun->AddPoint(3071, .80, 0.5, 0.0); 320 
321         mapper->SetBlendModeToComposite(); 322         property->ShadeOn(); 323         property->SetAmbient(0.1); 324         property->SetDiffuse(0.9); 325         property->SetSpecular(0.2); 326         property->SetSpecularPower(10.0); 327         property->SetScalarOpacityUnitDistance(0.8919); 328         break; 329 
330         // RGB_Composite 331         // Use compositing and functions set to highlight red/green/blue regions 332         // in RGB data. Not for use on single component data
333     case 6: 334         opacityFun->AddPoint(0, 0.0); 335         opacityFun->AddPoint(5.0, 0.0); 336         opacityFun->AddPoint(30.0, 0.05); 337         opacityFun->AddPoint(31.0, 0.0); 338         opacityFun->AddPoint(90.0, 0.0); 339         opacityFun->AddPoint(100.0, 0.3); 340         opacityFun->AddPoint(110.0, 0.0); 341         opacityFun->AddPoint(190.0, 0.0); 342         opacityFun->AddPoint(200.0, 0.4); 343         opacityFun->AddPoint(210.0, 0.0); 344         opacityFun->AddPoint(245.0, 0.0); 345         opacityFun->AddPoint(255.0, 0.5); 346 
347         mapper->SetBlendModeToComposite(); 348         property->ShadeOff(); 349         property->SetScalarOpacityUnitDistance(1.0); 350         break; 351     default: 352         vtkGenericWarningMacro("Unknown blend type."); 353         break; 354  } 355 
356     // Set the default window size
357     renWin->SetSize(600, 600); 358     renWin->Render(); 359 
360     // Add the volume to the scene
361     renderer->AddVolume(volume); 362 
363     renderer->ResetCamera(); 364     renderer->SetBackground(colors->GetColor3d("SlateGray").GetData()); 365 
366     // interact with data
367     renWin->Render(); 368 
369     iren->Start(); 370 
371     return EXIT_SUCCESS;; 372 }

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM