From 183710c2f0a135f129ccc40fe8c2af70ed9d35fb Mon Sep 17 00:00:00 2001 From: bouilhol Date: Fri, 5 Nov 2010 00:04:59 +0000 Subject: [PATCH] clitkDicomToImage added to clitk3 --- tools/CMakeLists.txt | 6 +- tools/clitkDicom2Image.cxx | 188 +++++++++++++++++++++++++++++++++++++ tools/clitkDicom2Image.ggo | 12 +++ 3 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 tools/clitkDicom2Image.cxx create mode 100644 tools/clitkDicom2Image.ggo diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 02a0511..8157242 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -24,7 +24,11 @@ TARGET_LINK_LIBRARIES(clitkBinarizeImageLib clitkToolsGgoLib) IF (CLITK_BUILD_TOOLS) WRAP_GGO(clitkDicomInfo_GGO_C clitkDicomInfo.ggo) ADD_EXECUTABLE(clitkDicomInfo clitkDicomInfo.cxx ${clitkDicomInfo_GGO_C}) - TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon ITKIO) + TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon ITKIO) + + WRAP_GGO(clitkDicom2Image_GGO_C clitkDicom2Image.ggo) + ADD_EXECUTABLE(clitkDicom2Image clitkDicom2Image.cxx ${clitkDicom2Image_GGO_C}) + TARGET_LINK_LIBRARIES(clitkDicom2Image clitkCommon ITKIO) WRAP_GGO(clitkImageInfo_GGO_C clitkImageInfo.ggo) ADD_EXECUTABLE(clitkImageInfo clitkImageInfo.cxx ${clitkImageInfo_GGO_C}) diff --git a/tools/clitkDicom2Image.cxx b/tools/clitkDicom2Image.cxx new file mode 100644 index 0000000..bb38458 --- /dev/null +++ b/tools/clitkDicom2Image.cxx @@ -0,0 +1,188 @@ +/*========================================================================= + +Program: clitk +Module: $RCSfile: clitkDicom2Image.cxx,v $ +Language: C++ +Date: $Date: 2010/11/05 00:05:00 $ +Version: $Revision: 1.1 $ + +Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de +l'Image). All rights reserved. See Doc/License.txt or +http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +/** + ================================================= + * @file clitkDicom2Image.cxx + * @author David Sarrut + * @date 26 Oct 2006 + * + * @brief + * + =================================================*/ + +// clitk includes +#include "clitkDicom2Image_ggo.h" +#include +#include "clitkImageCommon.h" + +// itk include +#include "itkImageRegionIterator.h" +#include "itkImageRegionConstIterator.h" + +// Why this is needed ??? +//const double itk::NumericTraits::Zero = 0.0; + +//==================================================================== +int main(int argc, char * argv[]) { + + // init command line + GGO(clitkDicom2Image, args_info); + std::vector input_files; + ///if std_input is given, read the input files from stdin + if (args_info.std_input_given) + { + while (true) + { + std::string tmp; + std::cin >> tmp; + if(std::cin.good()) + input_files.push_back(tmp); + else break; + } + args_info.inputs_num=input_files.size(); + } + else for (unsigned int i=0;i sliceLocations; + for(unsigned int i=0; iGetZOrigin()); + // check + /*if (!header->IsSignedPixelData()) { + std::cerr << "Pixel type not signed ! " << std::endl; + std::cerr << "In file " << input_files[i] << std::endl; + exit(0); + }*/ + if (header->GetPixelSize() != 2) { + std::cerr << "Pixel type 2 bytes ! " << std::endl; + std::cerr << "In file " << input_files[i] << std::endl; + exit(0); + } + } + + //=========================================== + // Sort slices locations ... + std::vector sliceIndex; + clitk::GetSortedIndex(sliceLocations, sliceIndex); + if (args_info.verboseSliceLocation_flag) { + std::cout << sliceLocations[sliceIndex[0]] << " -> " + << sliceIndex[0] << " / " << 0 << " => " + << "0 mm " + << input_files[sliceIndex[0]] + << std::endl; + for(unsigned int i=1; i " + << sliceIndex[i] << " / " << i << " => " + << sliceLocations[sliceIndex[i]] - sliceLocations[sliceIndex[i-1]] + << "mm " + << input_files[sliceIndex[i]] + << std::endl; + } + } + + //=========================================== + // Analyze slices locations ... + double currentDist; + double dist=0; + double tolerance = args_info.tolerance_arg; + double previous = sliceLocations[sliceIndex[0]]; + for(unsigned int i=1; i tolerance) { + std::cout << "ERROR : " << std::endl + << "Current slice pos is = " << sliceLocations[sliceIndex[i]] << std::endl + << "Previous slice pos is = " << previous << std::endl + << "Current file is = " << input_files[sliceIndex[i]] << std::endl + << "Current index is = " << i << std::endl + << "Current sortindex is = " << sliceIndex[i] << std::endl + << "Current slice diff = " << dist << std::endl + << "Current error = " << fabs(dist-currentDist) << std::endl; + exit(1); + } + } + else dist = currentDist; + previous = sliceLocations[sliceIndex[i]]; + } + + //=========================================== + // Create image + gdcm::File * header = clitk::readDicomHeader(input_files[sliceIndex.front()]); + typedef itk::Image ImageType; + typedef itk::Image ImageTypeOutput; + ImageType::SpacingType spacing; + ImageType::SizeType size; + ImageType::PointType origin; + spacing[0] = header->GetXSpacing(); + spacing[1] = header->GetYSpacing(); + spacing[2] = dist; + size[0] = header->GetXSize(); + size[1] = header->GetYSize(); + size[2] = sliceIndex.size(); + ///Optional use of special origin scheme used at CLB + if (args_info.focal_origin_flag) + { + origin[0] = -spacing[0]*size[0]/2; + origin[1] = -spacing[1]*size[1]/2; + } + else + { + origin[0] = header->GetXOrigin(); + origin[1] = header->GetYOrigin(); + } + origin[2] = header->GetZOrigin(); + ImageTypeOutput::Pointer output = ImageTypeOutput::New(); + itk::ImageRegion<3> region; + region.SetSize(size); + output->SetRegions(region); + output->SetOrigin(origin); + output->SetSpacing(spacing); + output->Allocate(); + + //=========================================== + // Fill image + ImageType::Pointer slice; + typedef itk::ImageRegionIterator IteratorType; + typedef itk::ImageRegionConstIterator ConstIteratorType; + IteratorType po(output, output->GetLargestPossibleRegion()); + po.Begin(); + for(unsigned int i=0; i(input_files[sliceIndex[i]]); + ConstIteratorType pi(slice, slice->GetLargestPossibleRegion()); + while ( !pi.IsAtEnd() ) { + po.Set((signed short)pi.Get()); + ++po; + ++pi; + } + } + + //=========================================== + // Write image + clitk::writeImage(output, + args_info.output_arg, + args_info.verbose_flag); + + // this is the end my friend + return 0; +} diff --git a/tools/clitkDicom2Image.ggo b/tools/clitkDicom2Image.ggo new file mode 100644 index 0000000..fb51135 --- /dev/null +++ b/tools/clitkDicom2Image.ggo @@ -0,0 +1,12 @@ +# file clitkDicom2Image.ggo +package "clitk" +version "Try to convert a DICOM into an image (.hdr, .vox...)" + +option "config" - "Config file" string no +option "verbose" v "Verbose" flag off +option "verboseSliceLocation" - "Verbose slices locations" flag off +option "name" n "Display filename" flag off +option "tolerance" t "Tolerance for slice position" double default="0" no +option "output" o "Output image filename" string yes +option "std_input" - "Take the like of input file from stdin, to support huge lists of filenames" flag off +option "focal_origin" - "Output files with FOCAL-like origin, instead of the origin present in the dicom files" flag off -- 2.45.2