/*============================================================================= NOTE: THIS FILE IS A HANDMADE WRAPPER FOR THE ManagedITK PROJECT. Project: ManagedITK Program: Insight Segmentation & Registration Toolkit Module: itkManagedImageBase.cxx Language: C++/CLI Author: Dan Mueller Date: $Date: 2007-09-01 06:17:25 +1000 (Sat, 01 Sep 2007) $ Revision: $Revision: 2 $ Copyright (c) Queensland University of Technology (QUT) 2007. All rights reserved. Portions of this code are covered under the ITK and VTK copyright. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm 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. =============================================================================*/ #pragma once #pragma warning( disable : 4635 ) // Disable warnings about XML doc comments #ifndef __itkManagedImageBase_cxx #define __itkManagedImageBase_cxx // Include some useful ITK headers #pragma unmanaged #include "itkImageIOFactory.h" // Include some useful ManagedITK files #pragma managed #include "itkManagedDataObject.cxx" #include "itkManagedDataObjectWithReadWrite.cxx" #include "itkManagedIndex.cxx" #include "itkManagedContinuousIndex.cxx" #include "itkManagedPoint.cxx" #include "itkManagedOffset.cxx" #include "itkManagedPixelType.cxx" #include "itkManagedPixel.cxx" #include "itkManagedSize.cxx" #include "itkManagedSpacing.cxx" #include "itkManagedMatrix.cxx" #include "itkManagedImageRegion.cxx" #include "itkManagedExceptionObject.cxx" #include "itkManagedImageInformation.cxx" // Use some managed namespaces #using #using using namespace System; using namespace System::IO; using namespace System::Reflection; using namespace System::Diagnostics; using namespace System::Collections::Generic; namespace itk { /// ///This class is a managed wrapper for itk::ImageBase. /// public ref class itkImageBase abstract : itkDataObjectWithReadWrite { protected: itkPixelType^ m_PixelType; unsigned int m_Dimension; ///Protected constructor. itkImageBase ( ) : itkDataObjectWithReadWrite( ) { } public: ///Dispose of the managed object. ~itkImageBase ( ) { } ///Get the type of pixel this image contains. /// ///In native itk, images are templated over the pixel type: TPixel (eg. unsigned ///char, float, etc). In ManagedITK, to allow for the specification of image types ///at runtime, the itkPixelType and itkPixel classes were introduced. /// property itkPixelType^ PixelType { itkPixelType^ get( ) { return this->m_PixelType; } } ///Get the number of dimensions this image contains. /// ///In native itk, images are templated over the number of dimensions: VDimension. ///In ManagedITK, to allow for the specification of image types at runtime, ///this property was introduced. /// property unsigned int Dimension { unsigned int get( ) { return this->m_Dimension; } } ///Get the size of the image (from the LargestPossibleRegion). ///This method was added in ManagedITK for simplicity. property itkSize^ Size { virtual itkSize^ get()=0; } /// ///Get the physical size of the image of the image (element-wise multiplication ///of Size and Spacing). /// ///This method was added in ManagedITK for simplicity. property itkArray^ PhysicalSize { virtual itkArray^ get() { itkArray^ result = gcnew itkArray(this->Dimension); for (unsigned int i=0; iDimension; i++) result[i] = this->Size[i] * this->Spacing[i]; return result; } } ///Get/set the spacing between pixels of the image. property itkSpacing^ Spacing { virtual itkSpacing^ get()=0; virtual void set( itkSpacing^ spacing )=0; } ///Get/set the origin of the image in physical space. property itkPoint^ Origin { virtual itkPoint^ get()=0; virtual void set( itkPoint^ origin )=0; } /// ///Get the region object that defines the size and starting index ///for the largest possible region this image could represent. /// property itkImageRegion^ LargestPossibleRegion { virtual itkImageRegion^ get()=0; virtual void set ( itkImageRegion^ region )=0; } /// ///Get/set the region object that defines the size and starting index ///for the region of the image requested (i.e., the region of the ///image to be operated on by a filter). Setting the RequestedRegion ///does not cause the object to be modified. /// property itkImageRegion^ RequestedRegion { virtual itkImageRegion^ get()=0; virtual void set ( itkImageRegion^ region )=0; } /// ///Get/set the region object that defines the size and starting index ///of the region of the image currently loaded in memory. /// property itkImageRegion^ BufferedRegion { virtual itkImageRegion^ get()=0; virtual void set ( itkImageRegion^ region )=0; } ///Get the pointer to the underlying image data array. property IntPtr Buffer { virtual IntPtr get()=0; } ///Get the direction cosines of the image. The direction cosines are vectors that point from one pixel to the next. property itkMatrix^ Direction { virtual itkMatrix^ get()=0; virtual void set ( itkMatrix^ direction )=0; } /// ///Allocates the memory for an empty image. ///This is the method to use to create an image from scratch (ie. not from IO). ///The regions MUST have been set: call SetRegions() before calling this method. ///The buffer is NOT initialised: call FillBuffer() after calling this method. /// ///This method finalises the creation of the underlying native itk::Image. virtual void Allocate ( )=0; /// ///Convenience method to set the LargestPossibleRegion, BufferedRegion and RequestedRegion. /// ///The image region specifying the largest, requested, and buffered size. /// ///This method does not allocate the image, use Allocate for that purpose. /// virtual void SetRegions ( itkImageRegion^ regions )=0; /// ///Fills the image data with the given value. ///The image regions must be set before calling this method and ///the image must have been allocated. /// ///The pixel value to fill the image. virtual void FillBuffer ( itkPixel^ value )=0; ///Read and return the image information. ///The relative or absolute file path and name. ///An itkImageInformation structure containing the dimensions, pixeltype, ///size, spacing, etc. of the given image. ///This method was added in ManagedITK for simplicity. static itkImageInformation^ ReadInformation ( System::String^ filename ) { try { // Marshal string to std::string std::string stdFilename; itkObject::MarshalString( filename, stdFilename ); // Read the image information itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( stdFilename.c_str(), itk::ImageIOFactory::ReadMode ); if ( imageIO.IsNull() ) { throw gcnew NotSupportedException( "The given file type is not supported." ); return nullptr; } imageIO->SetFileName( stdFilename.c_str() ); imageIO->ReadImageInformation(); // Get the dim, size, spacing and origin unsigned int dim = imageIO->GetNumberOfDimensions(); itkSize^ size = gcnew itkSize( dim ); itkSpacing^ spacing = gcnew itkSpacing( dim ); itkPoint^ origin = gcnew itkPoint( dim ); for (unsigned int i=0; iGetSpacing( i ); origin[i] = imageIO->GetOrigin( i ); size[i] = imageIO->GetDimensions( i ); } // Get the pixel type itkPixelTypeEnum componentType = itkPixelTypeEnum::UnsignedChar; itkPixelArrayEnum arrayType = itkPixelArrayEnum::Scalar; switch (imageIO->GetComponentType()) { case itk::ImageIOBase::UCHAR: componentType = itkPixelTypeEnum::UnsignedChar; break; case itk::ImageIOBase::CHAR: componentType = itkPixelTypeEnum::SignedChar; break; case itk::ImageIOBase::USHORT: componentType = itkPixelTypeEnum::UnsignedShort; break; case itk::ImageIOBase::SHORT: componentType = itkPixelTypeEnum::SignedShort; break; case itk::ImageIOBase::ULONG: componentType = itkPixelTypeEnum::UnsignedLong; break; case itk::ImageIOBase::LONG: componentType = itkPixelTypeEnum::SignedLong; break; case itk::ImageIOBase::FLOAT: componentType = itkPixelTypeEnum::Float; break; case itk::ImageIOBase::DOUBLE: componentType = itkPixelTypeEnum::Double; break; default: throw gcnew NotSupportedException( "Unsupported pixel component type: " + ((int)imageIO->GetComponentType()).ToString() ); return nullptr; } switch (imageIO->GetPixelType()) { case itk::ImageIOBase::SCALAR: arrayType = itkPixelArrayEnum::Scalar; break; case itk::ImageIOBase::RGB: arrayType = itkPixelArrayEnum::ArrayRGB; break; case itk::ImageIOBase::RGBA: arrayType = itkPixelArrayEnum::ArrayRGBA; break; case itk::ImageIOBase::VECTOR: arrayType = itkPixelArrayEnum::ArrayVector; break; case itk::ImageIOBase::COVARIANTVECTOR: arrayType = itkPixelArrayEnum::ArrayCovariantVector; break; default: throw gcnew ApplicationException( "Unsupported pixel array type: " + ((int)imageIO->GetPixelType()).ToString() ); return nullptr; } itkPixelType^ pixeltype = gcnew itkPixelType( componentType, arrayType, imageIO->GetNumberOfComponents() ); // Return the information structure return gcnew itkImageInformation( pixeltype, dim, size, spacing, origin ); } catch ( itk::ExceptionObject& ex ) { throw gcnew itkExceptionObject( ex ); } catch ( Exception^ ex ) { System::String^ message = "Unable to read '" + System::IO::Path::GetFileName(filename) + "'."; throw gcnew ApplicationException(message, ex); } } ///Read an image series from the given filenames. ///An array of absolute file paths. ///This method was added in ManagedITK for simplicity. virtual void ReadSeries ( array^ filenames )=0; ///Read an image series from the files matching the given pattern. ///An absolute path to search for the files comprising the series. ///A pattern with wildcard character '*'. ///path="C:/temp/", pattern="test_*.png". ///This method was added in ManagedITK for simplicity. virtual void ReadSeries ( System::String^ path, System::String^ pattern ) { this->ReadSeries( System::IO::Directory::GetFiles(path, pattern) ); } /// ///Read an image from the given DICOM directory using GDCM. ///This method uses the first found series identifier. /// ///The directory containing the DICOM series. ///This method was added in ManagedITK for simplicity. virtual void ReadDicomDirectory( System::String^ directory ) = 0; ///Read an image from the given DICOM directory using GDCM. ///The directory containing the DICOM series. ///The identifier of the series to read. ///This method was added in ManagedITK for simplicity. virtual void ReadDicomDirectory( System::String^ directory, System::String^ seriesid ) = 0; ///Read an image from the given DICOM directory using GDCM. ///The directory containing the DICOM series. ///The identifier of the series to read. ///Specifies additional DICOM information to distinguish unique volumes within the directory. Eg. "0008|0021" distinguishes series based on date. ///This method was added in ManagedITK for simplicity. virtual void ReadDicomDirectory( System::String^ directory, System::String^ seriesid, ... array^ restrictions) = 0; ///Write an image series to the files matching the given format. The seriesFormat is "000". ///The absolute path and filename format for the images. Eg. C:/temp/test_{0}.png. ///filenameFormat="C:/temp/test_{0}.png". ///This method was added in ManagedITK for simplicity. virtual void WriteSeries ( System::String^ filenameFormat ) { this->WriteSeries( filenameFormat, "000" ); } ///Write an image series to the files matching the given format. ///The absolute path and filename format for the images. Eg. C:/temp/test_{0}.png. ///A format string for the series numbers. Eg. "000". ///filenameFormat="C:/temp/test_{0}.png" and seriesFormat="000". ///This method was added in ManagedITK for simplicity. virtual void WriteSeries ( System::String^ filenameFormat, System::String^ seriesFormat )=0; ///Returns the pixel value at the given discrete location. ///The discrete location in image space. ///The pixel value at the given discrete location. virtual itkPixel^ GetPixel ( itkIndex^ index )=0; ///Set the pixel value at the given discrete location. ///The discrete location in image space. ///The new value to set. virtual void SetPixel ( itkIndex^ index, itkPixel^ value )=0; ///Convert a physical point to a continuous index. ///The geometric location in physical space. ///The resultant continuous location in image space. ///true if the resulting index is within the image, false otherwise. virtual bool TransformPhysicalPointToContinuousIndex( itkPoint^ point, [System::Runtime::InteropServices::Out] itkContinuousIndex^% cindex )=0; ///Convert a physical point to a discrete index. ///The geometric location in physical space. ///The resultant discrete location in image space. ///true if the resulting index is within the image, false otherwise. virtual bool TransformPhysicalPointToIndex( itkPoint^ point, [System::Runtime::InteropServices::Out] itkIndex^% index )=0; ///Convert a continuous index to a physical point. ///The continuous location in image space. ///The resultant geometric location in physical space. virtual void TransformContinuousIndexToPhysicalPoint( itkContinuousIndex^ cindex, [System::Runtime::InteropServices::Out] itkPoint^% point )=0; ///Convert a discrete index to a physical point. ///The discrete location in image space. ///The resultant geometric location in physical space. virtual void TransformIndexToPhysicalPoint( itkIndex^ index, [System::Runtime::InteropServices::Out] itkPoint^% point )=0; /// ///Create a string representation of the image in the following format: /// "Size=[XX, XX, ..] Spacing=[XX, XX, ..] PixelType=ThePixelType" /// ///A string representation of the image including Size, Spacing, and PixelType. virtual String^ ToString() override { // Construct string String^ result = String::Empty; if (this->Size != nullptr) result += "Size=" + this->Size->ToString() + " "; if (this->Spacing != nullptr) result += "Spacing=" + this->Spacing->ToString() + " "; result += "PixelType=" + this->PixelType->LongTypeString; // Return return result; } }; // end ref class } // end namespace itk #endif