[Insight-users] How can I read DICOM files (more than 2 slices) by using ITK ?
Stuart Golodetz
itk at gxstudios.net
Fri Jun 4 06:53:34 EDT 2010
noc wrote:
> Hi all,
>
> Here Imet 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());
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20100604/06f24dca/attachment-0001.htm>
More information about the Insight-users
mailing list