Bryn <br><br>Thank you for the tip. I successfully connected the pipelines using the itkGDCM dicom series reader then used a itkcurvatureflowimagefilter and finally connected the ITK image to the vtk pipeline without writing an XML file using the vtkKWImage class and its SetITKImageBase. <br>
<br>A section of thecode is listed below for my future reference =)<br><br>I also reviewed the code you sugested for picking seed points. <a href="http://www.vision.ee.ethz.ch/%7Eblloyd/ImageViewer/" target="_blank">http://www.vision.ee.ethz.ch/~blloyd/ImageViewer/</a><br>
<br>I could not build the project I think the tar file is missing the Qt files and then I got some additional errors. My question is, I noticed that you write a xxx.txt file of the seeds you select with this application. <br>
<br>Do you later on read the seed.txt file in ITK? or can you export the seeds from VTK to ITK? <br><br>Thank you again. <br><br>Sergio <br><br><br><br> char fname[] = "/home/echopixel/Desktop/engine/code/seed/images";<br>
// DICOM READER <br> typedef unsigned short PixelType;<br> const unsigned int Dimension = 3;<br><br> typedef itk::Image< PixelType, Dimension > ImageType;<br><br> typedef itk::ImageSeriesReader< ImageType > ReaderType;<br>
ReaderType::Pointer reader = ReaderType::New();<br><br> typedef itk::GDCMImageIO ImageIOType;<br> ImageIOType::Pointer dicomIO = ImageIOType::New();<br> <br> reader->SetImageIO( dicomIO );<br><br> typedef itk::GDCMSeriesFileNames NamesGeneratorType;<br>
NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();<br> nameGenerator->SetUseSeriesDetails( true );<br> nameGenerator->SetDirectory( fname );<br><br> try<br> {<br> std::cout << std::endl << "The directory: " << std::endl;<br>
std::cout << std::endl << fname << std::endl << std::endl;<br> std::cout << "Contains the following DICOM Series: ";<br> std::cout << std::endl << std::endl;<br>
<br> typedef std::vector< std::string > SeriesIdContainer;<br> const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();<br> <br> SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();<br>
SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();<br> while( seriesItr != seriesEnd )<br> {<br> std::cout << seriesItr->c_str() << std::endl;<br> seriesItr++;<br> }<br>
<br> std::string seriesIdentifier;<br><br> if( argc > 3 ) // If no optional series identifier<br> {<br> seriesIdentifier = argv[3];<br> }<br> else<br> {<br> seriesIdentifier = seriesUID.begin()->c_str();<br>
}<br><br> std::cout << std::endl << std::endl;<br> std::cout << "Now reading series: " << std::endl << std::endl;<br> std::cout << seriesIdentifier << std::endl;<br>
std::cout << std::endl << std::endl;<br><br> typedef std::vector< std::string > FileNamesContainer;<br> FileNamesContainer fileNames;<br> fileNames = nameGenerator->GetFileNames( seriesIdentifier );<br>
<br> reader->SetFileNames( fileNames );<br> try<br> { //reader is handler to image stack (volume)<br> reader->Update(); // reader contaisn VOLUME stack as ITK Image<br> }<br> catch (itk::ExceptionObject &ex)<br>
{ //ctach any errors and print on screen<br> std::cout << ex << std::endl;<br> }<br><br> } // END OF TRY that Identified Series and led to TRY that triggers reading. <br> catch (itk::ExceptionObject &ex)<br>
{ // catch any errors and print on screen. <br> std::cout << ex << std::endl;<br> }<br><br> //Because CT Scanning has some offsets we must account for them - Slope and Intercept<br> double intercept = dicomIO->GetRescaleIntercept();<br>
double slope = dicomIO->GetRescaleSlope();<br><br> std::cout << "Rescale Intercept value: " << intercept << endl;<br> std::cout << "Rescale Slope value: " << slope << endl;<br>
// image = reader image is ITK image contains volume stack<br> ImageType::Pointer image = reader->GetOutput();<br> //Get original stack parameters ie SIZE X 512 Y 512 Z 400+ slices<br> ImageType::RegionType inputRegion = image->GetLargestPossibleRegion();<br>
ImageType::SizeType size = inputRegion.GetSize();<br> <br> int Xmax = size[0];<br> int Ymax = size[1];<br> int Zmax = size[2];<br> // Ajust Slope & Intercept Values to each VOXEL - Operate on same image through iterator IN<br>
typedef itk::ImageRegionIterator< ImageType > IteratorType;<br> IteratorType in( image, image->GetRequestedRegion() );<br> // For each voxel in stack - pointed by IN incorporate slope and rescale<br> for ( in.GoToBegin(); !in.IsAtEnd(); ++in) { <br>
in.Set( (in.Value() * slope) + (abs(intercept)));<br> }<br><br>// DICOM READER <br>// itk filter <br> itk::CurvatureFlowImageFilter<ImageType,ImageType>::Pointer cf = itk::CurvatureFlowImageFilter<ImageType,ImageType>::New();<br>
cf->SetInput( reader->GetOutput() );<br> //cf->SetInput(image);<br> std::cout << "Now doing ITK-Curvature Flow: " << std::endl << std::endl;<br> cf->SetTimeStep(0.25);<br> cf->SetNumberOfIterations(10);<br>
cf->Update();<br><br> vtkKWImage *kwImage = vtkKWImage::New();<br> kwImage->SetITKImageBase(cf->GetOutput());<br><br> vtkImageData *vtkImage = kwImage->GetVTKImage();<br><br> double range[2];<br> vtkImage->GetScalarRange(range);<br>
<br> vtkImageShiftScale* shifter = vtkImageShiftScale::New();<br> shifter->SetShift(-1.0*range[0]);<br> shifter->SetScale(255.0/(range[1]-range[0]));<br> shifter->SetOutputScalarTypeToUnsignedChar();<br> shifter->SetInput(vtkImage);<br>
shifter->ReleaseDataFlagOff();<br> shifter->Update();<br><br> vtkImageViewer2 *ImageViewer = vtkImageViewer2::New();<br> ImageViewer->SetInput(shifter->GetOutput());<br> ImageViewer->SetColorLevel(127);<br>
ImageViewer->SetColorWindow(255);<br> <br><br><br>