[Insight-users] How can I read DICOM files (more than 2 slices) by using ITK ?

noc hawkingyy at hotmail.com
Fri Jun 4 08:52:44 EDT 2010


Hi Stu,

 

First of all, thank you so much!!!

 

I tried the way in the ITK Software Guide, and it works!!!

Your codes work as well, however, it's a little difficult to understand ^_^

 

here is my code, hope to help someone who meets the same question.

--code--

 

int main( )
{

 typedef signed short    PixelType;
 const unsigned int      Dimension = 3;

 typedef itk::Image< PixelType, Dimension >         ImageType;

 typedef itk::ImageSeriesReader< ImageType >        ReaderType;
 ReaderType::Pointer reader1 = ReaderType::New();


 typedef itk::GDCMImageIO       ImageIOType;
 ImageIOType::Pointer dicomIO = ImageIOType::New();

 reader1->SetImageIO( dicomIO );

 typedef itk::GDCMSeriesFileNames NamesGeneratorType;
 NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();

 nameGenerator->SetUseSeriesDetails( true );
 nameGenerator->SetDirectory("d:/data/feet");


 try
 { 
  typedef std::vector< std::string >    SeriesIdContainer;

  const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();

  SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();
  SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();
  while( seriesItr != seriesEnd )
  {
   std::cout << seriesItr->c_str() << std::endl;
   seriesItr++;
  }


  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;


  typedef std::vector< std::string >   FileNamesContainer;
  FileNamesContainer fileNames;

  fileNames = nameGenerator->GetFileNames( seriesIdentifier );


  reader1->SetFileNames( fileNames );


  try
  {
   reader1->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;
 }
 return EXIT_FAILURE;

}
 

--code--

 

thanks again !

 

Regards,

 

Danile


Date: Fri, 4 Jun 2010 11:53:34 +0100
From: itk at gxstudios.net
To: hawkingyy at hotmail.com
CC: insight-users at itk.org
Subject: Re: [Insight-users] How can I read DICOM files (more than 2 slices) by using ITK ?

noc wrote: 


Hi all,
 
Here I met a problem.
 
I wanna use ITK to read many slices of DICOM files, and make them go though the BilateralImageFilter,
then, do marching cubes.
 
However, I can not deal with the reading methods, could anyone help me, please? Or just show me some examples.
 
Thanks a lot!
 
Regards,
 
Danile

Not sure if this will help or not (hope so), but the way I currently read a DICOM series looks like the below. It assumes that you've loaded in the set of image filenames you want to load from elsewhere (specifically, from a DICOMDIR file, for which I had to use the gdcm library separately from ITK). If you're doing it a different way, you can just specify imageFilenames explicitly. For an alternative method, see 7.11 in the ITK Software Guide (unless it's been updated since I downloaded my copy).

Cheers,
Stu

void DICOMVolumeLoader::execute()
try
{
    typedef itk::GDCMImageIO ImageIO;
    typedef itk::Image<int,2> Image2D;
    typedef itk::Image<int,3> Image3D;
    typedef itk::JoinSeriesImageFilter<Image2D,Image3D> Joiner;
    typedef itk::ImageFileReader<Image2D> Reader;
    typedef itk::RegionOfInterestImageFilter<Image2D,Image2D> RegionExtractor;

    // Set up the desired region for each of the slices.
    Image2D::RegionType region;
    Image2D::IndexType index = {{m_volumeChoice.minX, m_volumeChoice.minY}};
    Image2D::SizeType size = {{m_volumeChoice.maxX + 1 - m_volumeChoice.minX, m_volumeChoice.maxY + 1 - m_volumeChoice.minY}};
    region.SetIndex(index);
    region.SetSize(size);

    std::vector<std::string> imageFilenames = m_dicomdir->image_filenames(m_volumeChoice.patientKey, m_volumeChoice.studyKey, m_volumeChoice.seriesKey);
    std::vector<Image2D::Pointer> images(imageFilenames.size());
    for(int i=m_volumeChoice.minZ; i<=m_volumeChoice.maxZ; ++i)
    {
        std::string imageFilename = m_volumeChoice.filePrefix + imageFilenames[i];

        if(!is_aborted())
        {
            set_progress(i - m_volumeChoice.minZ);
            set_status("Loading image " + imageFilename + "...");
        }
        else return;

        // Load the image.
        Reader::Pointer reader = Reader::New();
        reader->SetFileName(imageFilename);
        ImageIO::Pointer gdcmImageIO = ImageIO::New();
        reader->SetImageIO(gdcmImageIO);
        reader->Update();

        // Extract the relevant sub-region.
        RegionExtractor::Pointer extractor = RegionExtractor::New();
        extractor->SetInput(reader->GetOutput());
        extractor->SetRegionOfInterest(region);
        extractor->Update();

        // Store the image.
        images[i] = extractor->GetOutput();
        images[i]->SetMetaDataDictionary(reader->GetMetaDataDictionary());
    }

    // Get the window centre and width if they haven't been explicitly specified by the user.
    if(m_volumeChoice.windowSettings.unspecified())
    {
        std::string windowCentreStr = read_header_field(images[m_volumeChoice.minZ], "0028|1050");
        std::string windowWidthStr = read_header_field(images[m_volumeChoice.minZ], "0028|1051");
        std::string validChars = "-0123456789";
        windowCentreStr = windowCentreStr.substr(0, windowCentreStr.find_first_not_of(validChars));
        windowWidthStr = windowWidthStr.substr(0, windowWidthStr.find_first_not_of(validChars));
        double windowCentre = lexical_cast<double>(windowCentreStr);
        double windowWidth = lexical_cast<double>(windowWidthStr);
        m_volumeChoice.windowSettings = WindowSettings(windowCentre, windowWidth);
    }

    // Make the images into a volume.
    Joiner::Pointer joiner = Joiner::New();

    double minSliceLocation = 0;
    try                         { minSliceLocation = lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ], "0020|1041")); }
    catch(bad_lexical_cast&)    { throw Exception("The SliceLocation value for the slice was not of the appropriate type"); }
    joiner->SetOrigin(minSliceLocation);

    double sliceThickness = 0;
    if(m_volumeChoice.minZ + 1 <= m_volumeChoice.maxZ)
    {
        try
        {
            double nextSliceLocation = lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ+1], "0020|1041"));
            sliceThickness = fabs(nextSliceLocation - minSliceLocation);
        }
        catch(bad_lexical_cast&)    {}
    }
    if(sliceThickness == 0)
    {
        try                         { sliceThickness = lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ], "0018|0050")); }
        catch(bad_lexical_cast&)    { throw Exception("The SliceThickness value for the slice was not of the appropriate type"); }
    }
    joiner->SetSpacing(sliceThickness);

    for(int i=m_volumeChoice.minZ; i<=m_volumeChoice.maxZ; ++i) joiner->PushBackInput(images[i]);
    joiner->Update();

    Image3D::Pointer volumeImage = joiner->GetOutput();
    m_volume.reset(new DICOMVolume(volumeImage));

    set_finished();
}
catch(std::exception& e)
{
    abort();
    set_status(e.what());
} 		 	   		  
_________________________________________________________________
约会说不清地方?来试试微软地图最新msn互动功能!
http://ditu.live.com/?form=TL&swm=1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20100604/303a57cd/attachment-0001.htm>


More information about the Insight-users mailing list