#ifndef _itk_GDCMImporter_h_ #define _itk_GDCMImporter_h_ #include #include #include #include #include #include #include #include #include #include namespace itk { /** \class DICOMVolume \brief Internal class that represent a 3D volume image made from 2D DICOM files. \author Nicolas Toussaint Don't use this class independently. The user may use GDCMImporter instead. \see GDCMImporter GDCMSeriesFileNames ImageSeriesReader \ingroup ProcessObject */ class DICOMVolume : public ProcessObject { public: typedef DICOMVolume Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef itk::Image FloatImageType; typedef itk::ImageFileReader ReaderType; typedef itk::ImageSeriesReader SeriesReaderType; typedef itk::FlipImageFilter FlipFilterType; itkNewMacro (Self); itkTypeMacro (DICOMVolume, ProcessObject); void SetImage(FloatImageType::Pointer image) { this->Image = image; } FloatImageType::Pointer GetImage(void) const { return this->Image; } void SetFileList(std::vector list) { this->FileList = list; } std::vector GetFileList (void) const { return this->FileList; } void SetDescription(std::string description) { this->Description = description; } std::string GetDescription (void) const { return this->Description; } void SetSerieHelper(gdcm::SerieHelper* helper) { this->SerieHelper = helper; } gdcm::SerieHelper* GetSerieHelper (void) const { return this->SerieHelper; } void SetgdcmFileList(std::vector *list) { this->gdcmFileList = list; } std::vector *GetgdcmFileList (void) const { return this->gdcmFileList; } unsigned int* GetDimensions(void); FloatImageType::Pointer TemporaryBuild (void); void Build(void); void Save (const char*); protected: DICOMVolume() { Description = ""; Image = 0; SerieHelper = 0; gdcmFileList = 0; } ~DICOMVolume(){} private : DICOMVolume(const Self&); void operator=(const Self&); std::string Description; FloatImageType::Pointer Image; std::vector FileList; gdcm::SerieHelper* SerieHelper; std::vector *gdcmFileList; }; /** \class GDCMImporter \brief itkProcessObject to manage DICOM files, reordering, building volumes \author Nicolas Toussaint This class is a powerfull factory for DICOM file management. It uses gdcm library from ITK to parse DICOM files and order them with respect to the GDCMSeriesFileNames strategy. The user can simply set the input directory with SetInputDirectory(). Then the directory will be scaned by calling Scan(). If you enconter some issues for reconstructing volumes (especially for interlaced files), you may use SplitVolumeByPositionConsistency() to reorder correctly the problematic volumes. When finished, you should call BuildAllVolumes() and recover all itkImages through the method GetDICOMVolumeList(). If for some reason you want to split a volume with respect to a certain DICOM tag, you can use SplitVolumeByTag(). \see GDCMImporter GDCMSeriesFileNames ImageSeriesReader \ingroup ProcessObject */ class GDCMImporter : public ProcessObject { public: /** generic typedefs */ typedef GDCMImporter Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** generic constructors */ itkNewMacro (Self); itkTypeMacro (GDCMImporter, ProcessObject); /** GDCMImporter's typedef, use GDCMImporter::FloatImageType as outputimage be match the templates */ typedef itk::Image FloatImageType; typedef itk::ImageFileReader ReaderType; typedef itk::ImageSeriesReader SeriesReaderType; typedef DICOMVolume::FlipFilterType FlipFilterType; /** DICOM tags : they are used to let the user sorting the DICOMs respecting a specific tag. More are to be added... */ enum DICOMTag { D_SERIESUID, D_STUDYDESCRIPTION, D_SERIESDESCRIPTION, D_ACQUISITIONTIME, D_MODALITY }; /** Set the recursive mode to ON if you want to scan DICOMs recursively in the InputDirectory */ itkBooleanMacro(Recursive); itkGetMacro (Recursive, bool); itkSetMacro (Recursive, bool); /** Set the direcory to scan in full path if you set the Recursive flag to ON, be carefull that set the write directory before scanning */ void SetInputDirectory (const char* path) { this->InputDirectory = path; } /* accessor */ const char* GetInputDirectory (void) const { return this->InputDirectory.c_str(); } /* check if a file can be read by itk::GDCMImageIO */ bool CanReadFile(const char* filename); /** Reset all buid volumes and filelists. dosen't reset the InputDirectory, so that the scanning would be faster afterward. */ void Reset (void); /** Scan the directory respecting the GDCMSeriesFileNames strategy, plus some rules the user may have added. it will create a list of DICOMVolume that can be access by GetDICOMVolumeList(). */ void Scan (void); /** Use this method for splitting volume with respect to a specific DICOM tag */ void SplitVolumeByTag (DICOMVolume::Pointer inputvolume, unsigned long tag); /** For most cases, this method is sufficient to correctly separate interlaced volumes */ void SplitVolumeByPositionConsistency (DICOMVolume::Pointer inputvolume); /** internal use */ static uint16_t GetDICOMTagGroup(unsigned long tag); /** internal use */ static uint16_t GetDICOMTagElement(unsigned long tag); /** Use this method to save a specific volume without keeping it in memory */ void Save(int, const char*); /** Save all volumes in a givem directory */ void SaveAll(const char*); /** internal use */ void AddVolume (std::string description, std::vector filelist, std::vector *gdcmfilelist); /** Access to the output reconstructed images */ std::vector GetOutputVolumes(void) const { return this->OutputVolumeList; } /** Pointers to DICOM volume objects */ std::vector GetDICOMVolumeList(void) const { return this->DICOMVolumeList; } /** Permanently remove a volume from the list */ void RemoveDICOMVolume (DICOMVolume::Pointer dcmvolume); /** Build 3D volumic images from 2D DICOM files */ void BuildAllVolumes (void); /** DEPRECATED */ enum SplitModeIds { NOSPLIT, SPLITFOLLOWED, SPLITINTERLACED }; /** internal use */ gdcm::XCoherentFileSetmap SplitOnPosition(gdcm::FileList *fileSet); protected: GDCMImporter(); ~GDCMImporter(); private: GDCMImporter(const Self&); void operator=(const Self&); std::string InputDirectory; bool m_Recursive; itk::GDCMSeriesFileNames::Pointer DICOMScanner; std::vector OutputVolumeList; std::vector DICOMVolumeList; }; } // end of namespace itk #endif