[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