/*============================================================================= 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: 2008-03-09 19:29:02 +0100 (Sun, 09 Mar 2008) $ Revision: $Revision: 8 $ Portions of this code are covered under the ITK and VTK copyright. See http://www.itk.org/HTML/Copyright.htm for details. See http://www.kitware.com/VTKCopyright.htm for details. Copyright (c) 2008 Queensland University of Technology (QUT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================================================*/ #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