[ITK] [ITK-users] Reading DICOM series and visualize the volume with VTK

Dženan Zukić dzenanz at gmail.com
Fri Mar 15 12:58:22 EDT 2019


Hi Marco,

that is more of a VTK question than ITK one, best directed at
vtkusers at vtk.org. Also, ITK has migrated to a new forum
<https://discourse.itk.org/>. Please post further ITK-related questions
there instead of this mailing list.

Regards,
Dženan

On Fri, Mar 15, 2019 at 12:54 PM Marco Festugato <marco.festugato at outlook.it>
wrote:

> Hi Dzenan and thank u for your answer 🙂 I've tried to do as u suggested,
> but i receive an error telling me that my mapper doesnt accept ''scalar
> cells''...maybe this connector doesnt work with my mapper? i've tried to
> simply add the 'connector' to my pipeline:
>
> reader -> connector -> mapper -> volume -> renderer -> window
>
> Here's my code if u want to check it (it still needs a bit of
> cleaning)...i would appreciate it a lot!! I need this to work for my
> project :'(
>
>  // VTK includes
> #include "vtkDICOMImageReader.h"
> #include "vtkImageData.h"
> #include "vtkRenderer.h"
> #include "vtkRenderWindow.h"
> #include "vtkRenderWindowInteractor.h"
> #include "vtkVolume.h"
> #include <vtkInteractorStyleTrackballCamera.h>
> #include <vtkVolumeProperty.h>
> #include <vtkSmartPointer.h>
> #include <vtkPiecewiseFunction.h>
> #include <vtkVolumeRayCastCompositeFunction.h>
> #include <vtkFixedPointVolumeRayCastMapper.h>
> #include <itkImage.h>
> #include <itkImageFileReader.h>
> #include <itkImageToVTKImageFilter.h>
> #include "vtkVersion.h"
> #include "vtkImageViewer.h"
> #include "vtkImageMapper3D.h"
> #include "vtkRenderWindowInteractor.h"
> #include "vtkSmartPointer.h"
> #include "vtkImageActor.h"
> #include "vtkInteractorStyleImage.h"
> #include "vtkRenderer.h"
> #include "itkImage.h"
> #include "itkGDCMImageIO.h"
> #include "itkGDCMSeriesFileNames.h"
> #include "itkImageSeriesReader.h"
> #include "itkImageFileWriter.h"
>
>  int main(int argc, char *argv[])
> {
>     // Verify the number of parameters in the command line
>     if( argc < 2)
>     {
>     std::cerr << "Usage: " << std::endl;
>     std::cerr << argv[0] << " DICOMimagesDirectory " << std::endl;
>     return EXIT_FAILURE;
>     }
>  // Software Guide : BeginCodeSnippet
>   typedef signed short    PixelType;
>   const unsigned int      Dimension = 3;
>   typedef itk::Image< PixelType, Dimension > ImageType;
>   typedef itk::ImageToVTKImageFilter<ImageType> ConnectorType;
>
>   ConnectorType::Pointer connector = ConnectorType::New();
>
> // We use the image type for instantiating the type of the series reader
> and
> // for constructing one object of its type.
>
>   typedef itk::ImageSeriesReader< ImageType >        ReaderType;
>   ReaderType::Pointer reader = ReaderType::New();
>
> // A GDCMImageIO object is created and connected to the reader. This
> object is
> // the one that is aware of the internal intricacies of the DICOM format.
> //
>
>   typedef itk::GDCMImageIO       ImageIOType;
>   ImageIOType::Pointer dicomIO = ImageIOType::New();
>
>   reader->SetImageIO( dicomIO );
>
>   using NamesGeneratorType = itk::GDCMSeriesFileNames;
>   NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
>
>   nameGenerator->SetUseSeriesDetails( true );
>   nameGenerator->SetDirectory( argv[1] );
>
>   try
>     {
>     std::cout << std::endl << "The directory: " << std::endl;
>     std::cout << std::endl << argv[1] << std::endl << std::endl;
>     std::cout << "Contains the following DICOM Series: ";
>     std::cout << std::endl << std::endl;
>
>
> // Software Guide : BeginLatex
> //
> // The GDCMSeriesFileNames object first identifies the list of DICOM series
> // present in the given directory. We receive that list in a reference
> // to a container of strings and then we can do things like print out all
> // the series identifiers that the generator had found. Since the process
> of
> // finding the series identifiers can potentially throw exceptions, it is
> // wise to put this code inside a \code{try/catch} block.
> //
>
>
>     typedef std::vector< std::string >    SeriesIdContainer;
>
>     const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
>
> // Given that it is common to find multiple DICOM series in the same
> directory,
> // we must tell the GDCM classes what specific series we want to read. In
> // this example we do this by checking first if the user has provided a
> series
> // identifier in the command line arguments. If no series identifier has
> been
> // passed, then we simply use the first series found during the
> exploration of
> // the directory.
>
>
>     std::string seriesIdentifier;
>
>      seriesIdentifier = seriesUID.begin()->c_str();
>
>     std::cout << std::endl << std::endl;
>     std::cout << "Now reading series: " << std::endl << std::endl;
>     std::cout << seriesIdentifier << std::endl;
>     std::cout << std::endl << std::endl;
>
>
> // We pass the series identifier to the name generator and ask for all the
> // filenames associated to that series. This list is returned in a
> container of
> // strings by the \code{GetFileNames()} method.
>
>
>     typedef std::vector< std::string >   FileNamesContainer;
>     FileNamesContainer fileNames;
>
>     fileNames = nameGenerator->GetFileNames( seriesIdentifier );
>
> //
> // The list of filenames can now be passed to the
> \doxygen{ImageSeriesReader}
> // using the \code{SetFileNames()} method.
>
>
>     reader->SetFileNames( fileNames );
>
> // Finally we can trigger the reading process by invoking the
> \code{Update()}
> // method in the reader. This call as usual is placed inside a
> \code{try/catch}
> // block.
>
>     try
>       {
>       reader->Update();
>       }
>     catch (itk::ExceptionObject &ex)
>       {
>       std::cout << ex << std::endl;
>       return EXIT_FAILURE;
>       }
> }
>   catch (itk::ExceptionObject &ex)
>     {
>     std::cout << ex << std::endl;
>     return EXIT_FAILURE;
>     }
>
>   // Visualization pipeline
>
>     // Create the renderer, render window and interactor
>    vtkRenderer *renderer = vtkRenderer::New();
>    vtkRenderWindow *renWin = vtkRenderWindow::New();
>    renWin->AddRenderer(renderer);
>
>     vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
>     iren->SetRenderWindow(renWin);
>
>    // Read the data
>    vtkImageData *input = nullptr;
>
> /*    vtkDICOMImageReader *reader = vtkDICOMImageReader::New();
> // vtkTIFFReader *reader = vtkTIFFReader::New();
>    reader->SetFileName(argv[1]); */
>    // reader->Update(); // read data
>
>
>    connector->SetInput(reader->GetOutput());
>
>     // Create our volume and mapper
>     vtkVolume *volume = vtkVolume::New();
>     vtkFixedPointVolumeRayCastMapper *mapper =
> vtkFixedPointVolumeRayCastMapper::New();
> // vtkVolumeRayCastCompositeFunction *compositeFunction =
> vtkVolumeRayCastCompositeFunction::New();
> vtkInteractorStyleTrackballCamera *styleCamera =
> vtkInteractorStyleTrackballCamera::New();
>
>     // connect up the volume to the property and the mapper
>     mapper -> SetInputData( connector -> GetOutput() );
> mapper -> SetSampleDistance( 0.1 );
>
> vtkSmartPointer<vtkVolumeProperty> volumeProperty =
> vtkSmartPointer<vtkVolumeProperty>::New();
>
>
> volumeProperty->SetInterpolationTypeToLinear(); // better image quality
> but computation's longer
>
>
> vtkSmartPointer<vtkPiecewiseFunction> scalarOpacity =
> vtkSmartPointer<vtkPiecewiseFunction>::New();
> vtkSmartPointer<vtkPiecewiseFunction> gradientOpacity =
> vtkSmartPointer<vtkPiecewiseFunction>::New();
>
>   scalarOpacity->AddPoint(0,    0.00);
>   scalarOpacity->AddPoint(500,  0.15);
>   scalarOpacity->AddPoint(1000, 0.15);
>   scalarOpacity->AddPoint(1150, 0.85);
>
>
>   gradientOpacity->AddPoint(0,   0.0);
>   gradientOpacity->AddPoint(90,  0.5);
>   gradientOpacity->AddPoint(100, 1.0);
>
>
> //set the transfer functions to the property
> volumeProperty->SetScalarOpacity(scalarOpacity);
> volumeProperty->SetGradientOpacity(gradientOpacity);
>
> //set the property to the volume
>
> volume->SetProperty(volumeProperty);
>
> volume->SetMapper( mapper );
>     iren -> SetInteractorStyle(styleCamera);
>     // Set the default window size
>     renWin->SetSize(600,600);
>
>     // Add the volume to the scene
>     renderer->AddVolume( volume );
>
>     // interact with data
>     renWin->Render();
>     iren -> Start();
>
>
>     return EXIT_SUCCESS;
>   }
>
>
>
> Inviato da Outlook <http://aka.ms/weboutlook>
> ------------------------------
> *Da:* Dženan Zukić <dzenanz at gmail.com>
> *Inviato:* venerdì 15 marzo 2019 17:19
> *A:* Marco Festugato
> *Cc:* insight-users at itk.org
> *Oggetto:* Re: [ITK-users] Reading DICOM series and visualize the volume
> with VTK
>
> Hi Marco,
>
> you could combine that example with VTK VolumeRendering
> <https://lorensen.github.io/VTKExamples/site/Cxx/VolumeRendering/SmartVolumeMapper/> example
> and connect them using ITKVTKGlue
> <https://itk.org/ITKExamples/src/Bridge/VtkGlue/ConvertAnitkImageTovtkImageData/Documentation.html>
> .
>
> Regards,
> Dženan
>
> On Fri, Mar 15, 2019 at 7:00 AM Marco Festugato <
> marco.festugato at outlook.it> wrote:
>
> Hi guys! I'm very new to ITK-VTK...what i have to do is reading 199 dicom
> images using ITK and visualize the volume using VTK.
> Using the example "DicomSeriesReadImageWrite2" im able to read the series
> and create a 3D volume but i dont know how to visualize it with VTK!
> Any help? :)
> Thank u for your time!
>
> Inviato da Outlook <http://aka.ms/weboutlook>
> The ITK community is transitioning from this mailing list to
> discourse.itk.org. Please join us there!
> ________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.php
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> https://itk.org/mailman/listinfo/insight-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://itk.org/pipermail/community/attachments/20190315/2a976fe1/attachment-0001.html>
-------------- next part --------------
The ITK community is transitioning from this mailing list to discourse.itk.org. Please join us there!
________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
https://itk.org/mailman/listinfo/insight-users


More information about the Community mailing list