<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=GB2312" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
noc wrote:
<blockquote cite="mid:SNT138-w426C1BDEF51315A1740D37BAD20@phx.gbl"
type="cite">
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>Hi
all,<br>
<br>
Here I met a problem.<br>
<br>
I wanna use ITK to read many slices of DICOM files, and make them go
though the BilateralImageFilter,<br>
then, do marching cubes.<br>
<br>
However, I can not deal with the reading methods, could anyone help me,
please? Or just show me some examples.<br>
<br>
Thanks a lot!<br>
<br>
Regards,<br>
<br>
Danile<br>
</blockquote>
<br>
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).<br>
<br>
Cheers,<br>
Stu<br>
<br>
void DICOMVolumeLoader::execute()<br>
try<br>
{<br>
typedef itk::GDCMImageIO ImageIO;<br>
typedef itk::Image<int,2> Image2D;<br>
typedef itk::Image<int,3> Image3D;<br>
typedef itk::JoinSeriesImageFilter<Image2D,Image3D> Joiner;<br>
typedef itk::ImageFileReader<Image2D> Reader;<br>
typedef itk::RegionOfInterestImageFilter<Image2D,Image2D>
RegionExtractor;<br>
<br>
// Set up the desired region for each of the slices.<br>
Image2D::RegionType region;<br>
Image2D::IndexType index = {{m_volumeChoice.minX,
m_volumeChoice.minY}};<br>
Image2D::SizeType size = {{m_volumeChoice.maxX + 1 -
m_volumeChoice.minX, m_volumeChoice.maxY + 1 - m_volumeChoice.minY}};<br>
region.SetIndex(index);<br>
region.SetSize(size);<br>
<br>
std::vector<std::string> imageFilenames =
m_dicomdir->image_filenames(m_volumeChoice.patientKey,
m_volumeChoice.studyKey, m_volumeChoice.seriesKey);<br>
std::vector<Image2D::Pointer> images(imageFilenames.size());<br>
for(int i=m_volumeChoice.minZ; i<=m_volumeChoice.maxZ; ++i)<br>
{<br>
std::string imageFilename = m_volumeChoice.filePrefix +
imageFilenames[i];<br>
<br>
if(!is_aborted())<br>
{<br>
set_progress(i - m_volumeChoice.minZ);<br>
set_status("Loading image " + imageFilename + "...");<br>
}<br>
else return;<br>
<br>
// Load the image.<br>
Reader::Pointer reader = Reader::New();<br>
reader->SetFileName(imageFilename);<br>
ImageIO::Pointer gdcmImageIO = ImageIO::New();<br>
reader->SetImageIO(gdcmImageIO);<br>
reader->Update();<br>
<br>
// Extract the relevant sub-region.<br>
RegionExtractor::Pointer extractor = RegionExtractor::New();<br>
extractor->SetInput(reader->GetOutput());<br>
extractor->SetRegionOfInterest(region);<br>
extractor->Update();<br>
<br>
// Store the image.<br>
images[i] = extractor->GetOutput();<br>
images[i]->SetMetaDataDictionary(reader->GetMetaDataDictionary());<br>
}<br>
<br>
// Get the window centre and width if they haven't been explicitly
specified by the user.<br>
if(m_volumeChoice.windowSettings.unspecified())<br>
{<br>
std::string windowCentreStr =
read_header_field(images[m_volumeChoice.minZ], "0028|1050");<br>
std::string windowWidthStr =
read_header_field(images[m_volumeChoice.minZ], "0028|1051");<br>
std::string validChars = "-0123456789";<br>
windowCentreStr = windowCentreStr.substr(0,
windowCentreStr.find_first_not_of(validChars));<br>
windowWidthStr = windowWidthStr.substr(0,
windowWidthStr.find_first_not_of(validChars));<br>
double windowCentre =
lexical_cast<double>(windowCentreStr);<br>
double windowWidth = lexical_cast<double>(windowWidthStr);<br>
m_volumeChoice.windowSettings = WindowSettings(windowCentre,
windowWidth);<br>
}<br>
<br>
// Make the images into a volume.<br>
Joiner::Pointer joiner = Joiner::New();<br>
<br>
double minSliceLocation = 0;<br>
try { minSliceLocation =
lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ],
"0020|1041")); }<br>
catch(bad_lexical_cast&) { throw Exception("The
SliceLocation value for the slice was not of the appropriate type"); }<br>
joiner->SetOrigin(minSliceLocation);<br>
<br>
double sliceThickness = 0;<br>
if(m_volumeChoice.minZ + 1 <= m_volumeChoice.maxZ)<br>
{<br>
try<br>
{<br>
double nextSliceLocation =
lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ+1],
"0020|1041"));<br>
sliceThickness = fabs(nextSliceLocation - minSliceLocation);<br>
}<br>
catch(bad_lexical_cast&) {}<br>
}<br>
if(sliceThickness == 0)<br>
{<br>
try { sliceThickness =
lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ],
"0018|0050")); }<br>
catch(bad_lexical_cast&) { throw Exception("The
SliceThickness value for the slice was not of the appropriate type"); }<br>
}<br>
joiner->SetSpacing(sliceThickness);<br>
<br>
for(int i=m_volumeChoice.minZ; i<=m_volumeChoice.maxZ; ++i)
joiner->PushBackInput(images[i]);<br>
joiner->Update();<br>
<br>
Image3D::Pointer volumeImage = joiner->GetOutput();<br>
m_volume.reset(new DICOMVolume(volumeImage));<br>
<br>
set_finished();<br>
}<br>
catch(std::exception& e)<br>
{<br>
abort();<br>
set_status(e.what());<br>
}
</body>
</html>