[vtkusers] [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://vtk.org/pipermail/vtkusers/attachments/20190315/2a976fe1/attachment.html>
More information about the vtkusers
mailing list