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 }

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

原文地址:https://www.cnblogs.com/ybqjymy/p/14239829.html