GDCM
2.0.18
|
00001 /*========================================================================= 00002 00003 Program: GDCM (Grassroots DICOM). A DICOM library 00004 00005 Copyright (c) 2006-2011 Mathieu Malaterre 00006 All rights reserved. 00007 See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. 00008 00009 This software is distributed WITHOUT ANY WARRANTY; without even 00010 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00011 PURPOSE. See the above copyright notice for more information. 00012 00013 =========================================================================*/ 00014 // .NAME vtkGDCMImageReader - read DICOM Image files (Pixel Data) 00015 // .SECTION Description 00016 // vtkGDCMImageReader is a source object that reads some DICOM files 00017 // this reader is single threaded. 00018 // .SECTION Implementation note: when FileLowerLeft is set to on the image is not flipped 00019 // upside down as VTK would expect, use this option only if you know what you are doing. 00020 // .SECTION Implementation note: when reading a series of 2D slices, user is 00021 // expected to provide an ordered list of filenames. No sorting will be applied afterward. 00022 // .SECTION Implementation note: Although 99% of the time the Zspacing as read 00023 // from a tag in a 2D DICOM file should be correct, there has been reports that this 00024 // value can be missing, or incorrect, in which case users are advised to override this 00025 // value using the return value from gdcm::IPPSorter::GetZSpacing() and set it via 00026 // vtkImageChangeInformation on the reader itself. 00027 // .SECTION TODO 00028 // This reader does not handle a series of 3D images, only a single 3D (multi frame) or a 00029 // list of 2D files are supported for now. 00030 // .SECTION TODO 00031 // Did not implement SetFilePattern / SetFilePrefix API, move it to protected section for now. 00032 // .SECTION BUG 00033 // Overlay are assumed to have the same extent as image. Right now if overlay origin is not 00034 // 0,0 the overlay will have an offset... 00035 // Only the very first overlay is loaded at the VTK level, for now (even if there are more than one in the file) 00036 // .SECTION DataOrigin 00037 // When the reader is instanciated with FileLowerLeftOn the DataOrigin and Image Position (Patient) are 00038 // identical. But when FileLowerLeft is Off, we have to reorder the Y-line of the image, and thus the DataOrigin 00039 // is then translated to the other side of the image. 00040 // .SECTION Spacing 00041 // When reading a 3D volume, the spacing along the Z dimension might be negative (so as to respect up-side-down) 00042 // as specified in the Image Orientation (Patient) tag. When Z-spacing is 0, this means the multi-frame object 00043 // contains image which do not represent uniform volume. 00044 // .SECTION Warning 00045 // When using vtkGDCMPolyDataReader in conjonction with vtkGDCMImageReader 00046 // it is *required* that FileLowerLeft is set to ON as coordinate system 00047 // would be inconsistant in between the two data structures. 00048 // .SECTION Color Space mapping: 00049 // * VTK_LUMINANCE <-> MONOCHROME2 00050 // * VTK_LUMINANCE_ALPHA <-> Not supported 00051 // * VTK_RGB <-> RGB 00052 // * VTK_RGBA <-> ARGB (deprecated, DICOM 2008) 00053 // * VTK_INVERSE_LUMINANCE <-> MONOCHROME1 00054 // * VTK_LOOKUP_TABLE <-> PALETTE COLOR 00055 // * VTK_YBR <-> YBR_FULL 00056 // 00057 // For detailed information on color space transformation and true lossless transformation see: 00058 // http://apps.sourceforge.net/mediawiki/gdcm/index.php?title=Color_Space_Transformations 00059 00060 // .SECTION See Also 00061 // vtkMedicalImageReader2 vtkMedicalImageProperties vtkGDCMPolyDataReader vtkGDCMImageWriter 00062 // vtkDICOMImageReader 00063 00064 #ifndef VTKGDCMIMAGEREADER_H 00065 #define VTKGDCMIMAGEREADER_H 00066 00067 #include "vtkMedicalImageReader2.h" 00068 #include "vtkImageData.h" 00069 00070 #if (VTK_MAJOR_VERSION >= 5) || ( VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 5 ) 00071 #else 00072 class vtkMedicalImageProperties; 00073 #endif 00074 #if ( VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION > 0 ) 00075 #else 00076 class vtkStringArray; 00077 #endif 00078 class vtkPolyData; 00079 00080 // vtkSystemIncludes.h defines: 00081 // #define VTK_LUMINANCE 1 00082 // #define VTK_LUMINANCE_ALPHA 2 00083 // #define VTK_RGB 3 00084 // #define VTK_RGBA 4 00085 #ifndef VTK_INVERSE_LUMINANCE 00086 #define VTK_INVERSE_LUMINANCE 5 00087 #endif 00088 #ifndef VTK_LOOKUP_TABLE 00089 #define VTK_LOOKUP_TABLE 6 00090 #endif 00091 #ifndef VTK_YBR 00092 #define VTK_YBR 7 00093 #endif 00094 #ifndef VTK_CMYK 00095 #define VTK_CMYK 8 00096 #endif 00097 00098 //BTX 00099 namespace gdcm { class ImageReader; } 00100 //ETX 00101 class vtkMatrix4x4; 00102 class VTK_EXPORT vtkGDCMImageReader : public vtkMedicalImageReader2 00103 { 00104 public: 00105 static vtkGDCMImageReader *New(); 00106 vtkTypeRevisionMacro(vtkGDCMImageReader,vtkMedicalImageReader2); 00107 virtual void PrintSelf(ostream& os, vtkIndent indent); 00108 00109 // Description: is the given file name a DICOM file containing an image ? 00110 virtual int CanReadFile(const char* fname); 00111 00112 // Description: 00113 // Valid extensions 00114 virtual const char* GetFileExtensions() 00115 { 00116 // I would like to get rid of ACR/NEMA/IMA so only allow dcm extension for now 00117 return ".dcm .DCM"; 00118 } 00119 00120 // Description: 00121 // A descriptive name for this format 00122 virtual const char* GetDescriptiveName() 00123 { 00124 return "DICOM"; 00125 } 00126 00127 // Description: 00128 // Get the Image Position (Patient) as stored in the DICOM file 00129 // This is a read-only data member 00130 vtkGetObjectMacro(DirectionCosines, vtkMatrix4x4); 00131 00132 #if (VTK_MAJOR_VERSION >= 5) || ( VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 5 ) 00133 #else 00134 // Description: 00135 // Get the medical image properties object 00136 vtkGetObjectMacro(MedicalImageProperties, vtkMedicalImageProperties); 00137 #endif 00138 virtual void SetMedicalImageProperties(vtkMedicalImageProperties *pd); 00139 00140 #if ( VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION > 0 ) 00141 #else 00142 virtual void SetFileNames(vtkStringArray*); 00143 vtkGetObjectMacro(FileNames, vtkStringArray); 00144 #endif 00145 00146 // Description: 00147 // Specifically request to load the overlay into the gdcm-VTK layer (gdcm always loads them when found). 00148 // If no overlay is found in the image, then the vtkImageData for the overlay will be empty. 00149 vtkGetMacro(LoadOverlays,int); 00150 vtkSetMacro(LoadOverlays,int); 00151 vtkBooleanMacro(LoadOverlays,int); 00152 00153 // Description: 00154 // Set/Get whether or not to load the Icon as vtkImageData (if found in the DICOM file) 00155 vtkGetMacro(LoadIconImage,int); 00156 vtkSetMacro(LoadIconImage,int); 00157 vtkBooleanMacro(LoadIconImage,int); 00158 00159 // Description: 00160 // Set/Get whether or not the image was compressed using a lossy compression algorithm 00161 vtkGetMacro(LossyFlag,int); 00162 vtkSetMacro(LossyFlag,int); 00163 vtkBooleanMacro(LossyFlag,int); 00164 00165 // Description: 00166 // Read only: number of overlays as found in this image (multiple overlays per slice is allowed) 00167 // Only valid when LoadOverlays is true 00168 vtkGetMacro(NumberOfOverlays,int); 00169 00170 // Description: 00171 // Read only: number of icon image (there can only be zero or one icon per file) 00172 // Only valid when LoadIconImage is true 00173 vtkGetMacro(NumberOfIconImages,int); 00174 00175 // Description: 00176 // Get Overlay/IconImage 00177 // Remember to ALWAYS use those methods in your code, as the internal number for the output port 00178 // is not garantee to remain the same, as features are added to the reader 00179 #if (VTK_MAJOR_VERSION >= 5) || ( VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 5 ) 00180 //FIXME: Need to get rid of BTX/ETX if only the Python Wrapper of VTK 4.2 would let me 00181 //BTX 00182 vtkAlgorithmOutput* GetOverlayPort(int index); 00183 vtkAlgorithmOutput* GetIconImagePort(); 00184 //ETX 00185 #endif 00186 vtkImageData* GetOverlay(int i); 00187 vtkImageData* GetIconImage(); 00188 00189 // Description: 00190 // Load image with its associated Lookup Table 00191 vtkGetMacro(ApplyLookupTable,int); 00192 vtkSetMacro(ApplyLookupTable,int); 00193 vtkBooleanMacro(ApplyLookupTable,int); 00194 00195 // Description: 00196 // Load image as YBR 00197 vtkGetMacro(ApplyYBRToRGB,int) 00198 vtkSetMacro(ApplyYBRToRGB,int) 00199 vtkBooleanMacro(ApplyYBRToRGB,int); 00200 00201 // Description: 00202 // Return VTK_LUMINANCE, VTK_INVERSE_LUMINANCE, VTK_RGB, VTK_RGBA, VTK_LOOKUP_TABLE, VTK_YBR or VTK_CMYK 00203 // or 0 when ImageFormat is not handled. 00204 // Warning: For color image, PlanarConfiguration need to be taken into account. 00205 vtkGetMacro(ImageFormat,int); 00206 00207 // Description: 00208 // Return the Planar Configuration. This simply means that the internal DICOM image was stored 00209 // using a particular planar configuration (most of the time: 0) 00210 // For monochrome image, PlanarConfiguration is always 0 00211 vtkGetMacro(PlanarConfiguration,int); 00212 00213 // Description: 00214 // Return the 'raw' information stored in the DICOM file: 00215 // In case of a series of multiple files, only the first file is considered. The Image Orientation (Patient) 00216 // is garantee to remain the same, and image Image Position (Patient) in other slice can be computed 00217 // using the ZSpacing (3rd dimension) 00218 // (0020,0032) DS [87.774866\-182.908510\168.629671] # 32, 3 ImagePositionPatient 00219 // (0020,0037) DS [0.001479\0.999989\-0.004376\-0.002039\-0.004372\-0.999988] # 58, 6 ImageOrientationPatient 00220 vtkGetVector3Macro(ImagePositionPatient,double); 00221 vtkGetVector6Macro(ImageOrientationPatient,double); 00222 00223 // Description: 00224 // Set/Get the first Curve Data: 00225 vtkGetObjectMacro(Curve,vtkPolyData); 00226 virtual void SetCurve(vtkPolyData *pd); 00227 00228 // Description: 00229 // \DEPRECATED: 00230 // Modality LUT 00231 // Value returned by GetShift/GetScale might be innacurate since Shift/Scale could be 00232 // varying along the Series read. Therefore user are advices not to use those functions 00233 // anymore 00234 vtkGetMacro(Shift,double); 00235 vtkGetMacro(Scale,double); 00236 00237 protected: 00238 vtkGDCMImageReader(); 00239 ~vtkGDCMImageReader(); 00240 00241 vtkSetVector6Macro(ImageOrientationPatient,double); 00242 00243 //BTX 00244 void FillMedicalImageInformation(const gdcm::ImageReader &reader); 00245 //ETX 00246 int RequestInformationCompat(); 00247 int RequestDataCompat(); 00248 00249 #if (VTK_MAJOR_VERSION >= 5) || ( VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 5 ) 00250 int ProcessRequest(vtkInformation* request, 00251 vtkInformationVector** inputVector, 00252 vtkInformationVector* outputVector); 00253 int RequestInformation(vtkInformation *request, 00254 vtkInformationVector **inputVector, 00255 vtkInformationVector *outputVector); 00256 int RequestData(vtkInformation *request, 00257 vtkInformationVector **inputVector, 00258 vtkInformationVector *outputVector); 00259 #else /*(VTK_MAJOR_VERSION >= 5) || ( VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 5 )*/ 00260 void ExecuteInformation(); 00261 void ExecuteData(vtkDataObject *out); 00262 #endif /*(VTK_MAJOR_VERSION >= 5) || ( VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 5 )*/ 00263 00264 protected: 00265 #if (VTK_MAJOR_VERSION >= 5) || ( VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 5 ) 00266 #else 00267 // Description: 00268 // Medical Image properties 00269 vtkMedicalImageProperties *MedicalImageProperties; 00270 #endif 00271 #if ( VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION > 0 ) 00272 #else 00273 vtkStringArray *FileNames; 00274 #endif 00275 00276 vtkMatrix4x4 *DirectionCosines; 00277 int LoadOverlays; 00278 int NumberOfOverlays; 00279 int LoadIconImage; 00280 int NumberOfIconImages; 00281 int IconImageDataExtent[6]; 00282 double ImagePositionPatient[3]; 00283 double ImageOrientationPatient[6]; 00284 vtkPolyData *Curve; 00285 00286 int ImageFormat; 00287 // the following 3, should remain optional 00288 int ApplyInverseVideo; 00289 int ApplyLookupTable; 00290 int ApplyYBRToRGB; 00291 // I think that planar configuration need to always be applied as far as VTK is concerned 00292 int ApplyPlanarConfiguration; 00293 int ApplyShiftScale; 00294 00295 int LoadSingleFile(const char *filename, char *pointer, unsigned long &outlen); 00296 00297 double Shift; 00298 double Scale; 00299 int IconDataScalarType; 00300 int IconNumberOfScalarComponents; 00301 int PlanarConfiguration; 00302 int LossyFlag; 00303 int ForceRescale; 00304 00305 protected: 00306 // TODO / FIXME 00307 void SetFilePrefix(const char *) {} 00308 vtkGetStringMacro(FilePrefix); 00309 void SetFilePattern(const char *) {} 00310 vtkGetStringMacro(FilePattern); 00311 00312 private: 00313 vtkGDCMImageReader(const vtkGDCMImageReader&); // Not implemented. 00314 void operator=(const vtkGDCMImageReader&); // Not implemented. 00315 }; 00316 #endif