[Insight-users] DICOM import doesn't work properly
Raphael Hoever
hoever at vision.ee.ethz.ch
Wed May 10 12:20:11 EDT 2006
Hi,
I am trying to import DICOM images with ITK. I tested
itk::DICOMImageIO2, itk::DicomImageIO and itk::GDCMImageIO for the
import interface but no matter what I do the pixel values of the images
are shifted by a very large number (64,512 = 11111100 00000000) and
since the InputPixelType is unsigned short (the DICOM images allocated
16 bit per pixel and use the lower 12 bit for the data) I observe
overflows at high intensity values. So for instance if the original
pixel intensity is 4095 the pixel value in the output image is (4095 +
64512)mod216 = 3071.
I am using ITK 2.6 and the DICOM images are from a Siemens Sensation 64
scanner.
Here is my code for reading just one DICOM image (the result is the same
if I read the whole sequence) and exporting it as a 16 bit tif image
(also unsigned char, so the cast filter is not mandatory):
int main( int argc, char* argv[] ) {
// check number of command line arguments
if( argc < 6 ) {
std::cerr << "Usage: " << std::endl;
std::cerr << argv[0] << " DicomDirectory outputFileName factorX
factorY factorZ"
<< std::endl;
return EXIT_FAILURE;
}
//parse command line to variables
const char *directoryName = argv[1];
const char *outputFileName = argv[2];
const double factorX = atof( argv[3] );
const double factorY = atof( argv[4] );
const double factorZ = atof( argv[5] );
//set number of image dimensions
const unsigned int Dimension = 3;
//set data format of pixels
typedef unsigned short InputPixelType;
typedef unsigned short OutputPixelType;
//create objects for input and output images
typedef itk::Image< InputPixelType, Dimension > InputImageType;
typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
//create reader object for image
typedef itk::ImageFileReader< InputImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
//create IO interface for DICOM images
typedef itk::DICOMImageIO2 ImageIOType;
ImageIOType::Pointer dicomIO = ImageIOType::New();
//connect reader object with DICOM IO interface
reader->SetImageIO( dicomIO );
//create object to generate DICOM file names
typedef itk::GDCMSeriesFileNames NamesGeneratorType;
NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
//tell nameGenerator the DICOM directory
nameGenerator->SetDirectory( directoryName );
try {
std::cout << std::endl << "The directory: " << std::endl;
std::cout << std::endl << directoryName << std::endl << std::endl;
std::cout << "Contains the following DICOM Series: ";
std::cout << std::endl << std::endl;
//generate container object with DICOM series UIDs
typedef std::vector< std::string > SeriesIdContainer;
const SeriesIdContainer &seriesUID = nameGenerator->GetSeriesUIDs();
//loop over DICOM series UIDs and print them
SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();
SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();
while( seriesItr != seriesEnd ) {
std::cout << seriesItr->c_str() << std::endl;
seriesItr++;
}
//get first DICOM series UID
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;
//generate container with all DICOM file names of the current series
typedef std::vector< std::string > FileNamesContainer;
FileNamesContainer fileNames;
fileNames = nameGenerator->GetFileNames( seriesIdentifier );
//tell reader file names
reader->SetFileName( fileNames.begin()->c_str() );
//read files from disk
try {
reader->Update();
}
catch (itk::ExceptionObject &ex) {
std::cout << ex << std::endl;
return EXIT_FAILURE;
}
//create cast filter to cast inputImage into output image data
structure
typedef itk::CastImageFilter< InputImageType, OutputImageType>
CastFilterType;
CastFilterType::Pointer caster = CastFilterType::New();
//set input of caster to inputImage
caster->SetInput( reader->GetOutput() );
//create image file writer
typedef itk::ImageFileWriter< OutputImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
//tell writer output file name and connect it to caster
writer->SetFileName( outputFileName );
writer->SetInput( caster->GetOutput() );
std::cout << "Writing the image as " << std::endl << std::endl;
std::cout << outputFileName << std::endl << std::endl;
//write output file
try {
writer->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_SUCCESS;
}
If I use the same code (without the DICOM import interface) for
importing tif images it works without any problems. I already thought
about a problwm with the byte order (little endian <-> big endian) but
this wouldn't make sense either. I would appreciate your help since I
have no clue where that bug comes from.
Cheers,
Raphael
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hoever.vcf
Type: text/x-vcard
Size: 354 bytes
Desc: not available
Url : http://public.kitware.com/pipermail/insight-users/attachments/20060510/b395669a/hoever.vcf
More information about the Insight-users
mailing list