diff --git a/Core/Code/Algorithms/mitkCompareImageFilter.cpp b/Core/Code/Algorithms/mitkCompareImageDataFilter.cpp similarity index 67% rename from Core/Code/Algorithms/mitkCompareImageFilter.cpp rename to Core/Code/Algorithms/mitkCompareImageDataFilter.cpp index c00f92651d..9e78c1d88c 100644 --- a/Core/Code/Algorithms/mitkCompareImageFilter.cpp +++ b/Core/Code/Algorithms/mitkCompareImageDataFilter.cpp @@ -1,106 +1,122 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include "mitkCompareImageFilter.h" + +// mitk includes +#include "mitkCompareImageDataFilter.h" #include "mitkImageAccessByItk.h" #include "mitkITKImageImport.h" +#include "mitkImageCaster.h" +#include "mitkMultiChannelImageDataComparisonFilter.h" +// itk includes #include -mitk::CompareImageFilter::CompareImageFilter() +mitk::CompareImageDataFilter::CompareImageDataFilter() { this->SetNumberOfRequiredInputs(2); } -void mitk::CompareImageFilter::GenerateData() +void mitk::CompareImageDataFilter::GenerateData() { // check inputs const mitk::Image* input1 = this->GetInput(0); const mitk::Image* input2 = this->GetInput(1); - // check input validity - if( input1->GetDimension() == input2->GetDimension() ) + // Generally this filter is part of the mitk::Image::Equal() method and only checks the equality of the image data + // so no further image type comparison is performed! + // CAVE: If the images differ in a parameter other then the image data, the filter may fail!! + + // check what number of components the inputs have + if(input1->GetPixelType().GetNumberOfComponents() == 1 && + input2->GetPixelType().GetNumberOfComponents() == 1) { AccessByItk_1( input1, EstimateValueDifference, input2); } + else if(input1->GetPixelType().GetNumberOfComponents() > 1 && + input2->GetPixelType().GetNumberOfComponents() > 1 ) + { + MultiChannelImageDataComparisonFilter::Pointer mcComparator = MultiChannelImageDataComparisonFilter::New(); + mcComparator->SetTestImage(input1); + mcComparator->SetValidImage(input2); + mcComparator->SetCompareFilterResult( &m_CompareDetails); + mcComparator->Update(); + //mcComparator->GetCompareFilterResult() + } } -#include "mitkImageCaster.h" - -bool mitk::CompareImageFilter::GetResult(size_t threshold) +bool mitk::CompareImageDataFilter::GetResult(size_t threshold) { if (! m_CompareResult) { return false; } if( m_CompareDetails.m_PixelsWithDifference > threshold ) { return false; } return true; } template< typename TPixel, unsigned int VImageDimension> -void mitk::CompareImageFilter::EstimateValueDifference(itk::Image< TPixel, VImageDimension>* itkImage1, +void mitk::CompareImageDataFilter::EstimateValueDifference(itk::Image< TPixel, VImageDimension>* itkImage1, const mitk::Image* referenceImage) { typedef itk::Image< TPixel, VImageDimension> InputImageType; typedef itk::Image< double, VImageDimension > OutputImageType; typename InputImageType::Pointer itk_reference = InputImageType::New(); mitk::CastToItkImage( referenceImage, itk_reference ); typedef itk::Testing::ComparisonImageFilter< InputImageType, OutputImageType > CompareFilterType; typename CompareFilterType::Pointer compare_filter = CompareFilterType::New(); compare_filter->SetTestInput( itkImage1 ); compare_filter->SetValidInput( itk_reference ); try { compare_filter->Update(); } catch( const itk::ExceptionObject& e) { m_CompareDetails.m_FilterCompleted = false; m_CompareDetails.m_ExceptionMessage = e.what(); MITK_WARN << e.what(); m_CompareResult = false; return; } // the filter has completed the calculation m_CompareResult = true; m_CompareDetails.m_FilterCompleted = true; m_CompareDetails.m_MaximumDifference = compare_filter->GetMaximumDifference(); m_CompareDetails.m_MinimumDifference = compare_filter->GetMinimumDifference(); m_CompareDetails.m_MeanDifference = compare_filter->GetMeanDifference(); m_CompareDetails.m_TotalDifference = compare_filter->GetTotalDifference(); m_CompareDetails.m_PixelsWithDifference = compare_filter->GetNumberOfPixelsWithDifferences(); mitk::Image::Pointer output = mitk::GrabItkImageMemory( compare_filter->GetOutput() ); this->SetOutput( MakeNameFromOutputIndex(0), output.GetPointer() ); - - } diff --git a/Core/Code/Algorithms/mitkCompareImageFilter.h b/Core/Code/Algorithms/mitkCompareImageDataFilter.h similarity index 91% rename from Core/Code/Algorithms/mitkCompareImageFilter.h rename to Core/Code/Algorithms/mitkCompareImageDataFilter.h index 54d166a9fe..bfeb491d87 100644 --- a/Core/Code/Algorithms/mitkCompareImageFilter.h +++ b/Core/Code/Algorithms/mitkCompareImageDataFilter.h @@ -1,118 +1,118 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef MITKCOMPAREIMAGEFILTER_H -#define MITKCOMPAREIMAGEFILTER_H +#ifndef MITKCOMPAREIMAGEDATAFILTER_H +#define MITKCOMPAREIMAGEDATAFILTER_H //MITK #include "mitkImageToImageFilter.h" #include "mitkImage.h" //ITK #include namespace mitk { /** * @brief A simple struct to hold the result of the comparison filter. */ struct CompareFilterResults { void PrintSelf() { if( !m_FilterCompleted ) { MITK_INFO << "Comparision filter terminated due to an exception: \n " << m_ExceptionMessage; return; } MITK_INFO << "Min. difference: " << m_MinimumDifference <<"\n" << "Max. difference: " << m_MaximumDifference <<"\n" << "Total difference: " << m_TotalDifference <<"\n" << "Mean difference: " << m_MeanDifference <<"\n" << "Number of pixels with differences: " << m_PixelsWithDifference; } double m_MinimumDifference; double m_MaximumDifference; double m_TotalDifference; double m_MeanDifference; size_t m_PixelsWithDifference; bool m_FilterCompleted; std::string m_ExceptionMessage; }; /** * @brief Filter for comparing two mitk::Image objects by pixel values * * The comparison is pixel-wise, the filter uses the itk::Testing::ComparisonImageFilter * to find differences. The filter expects two images as input, provide them by using the SetInput( int, mitk::Image) * method. */ -class MITK_CORE_EXPORT CompareImageFilter +class MITK_CORE_EXPORT CompareImageDataFilter : public ImageToImageFilter { public: - mitkClassMacro(CompareImageFilter, + mitkClassMacro(CompareImageDataFilter, ImageToImageFilter) itkSimpleNewMacro(Self) /** * @brief Get the result of the comparision * * The method compares only the number of pixels with differences. It returns true if the amount * is under the specified threshold. To get the complete results, use the GetCompareResults method. * * Returns false also if the itk ComparisionImageFilter raises an exception during update. * * @param threshold Allowed amount of pixels with differences */ bool GetResult(size_t threshold = 0); /** * @brief Get the detailed results of the comparision run * * @sa CompareFilterResults */ CompareFilterResults GetCompareResults() { return m_CompareDetails; } protected: - CompareImageFilter(); - virtual ~CompareImageFilter() {} + CompareImageDataFilter(); + virtual ~CompareImageDataFilter() {} virtual void GenerateData(); /** ITK-like method which calls the ComparisionFilter on the two inputs of the filter */ template< typename TPixel, unsigned int VImageDimension> void EstimateValueDifference( itk::Image< TPixel, VImageDimension>* itkImage1, const mitk::Image* referenceImage); bool m_CompareResult; CompareFilterResults m_CompareDetails; }; } // end namespace mitk -#endif // MITKCOMPAREIMAGEFILTER_H +#endif // MITKCompareImageDataFilter_H diff --git a/Core/Code/Algorithms/mitkMultiChannelImageDataComparisonFilter.cpp b/Core/Code/Algorithms/mitkMultiChannelImageDataComparisonFilter.cpp new file mode 100644 index 0000000000..986d2f6941 --- /dev/null +++ b/Core/Code/Algorithms/mitkMultiChannelImageDataComparisonFilter.cpp @@ -0,0 +1,183 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +// mitk includes +#include "mitkMultiChannelImageDataComparisonFilter.h" +#include "mitkImageReadAccessor.h" +#include "mitkImagePixelReadAccessor.h" + +// other includes +#include + +namespace mitk +{ + + MultiChannelImageDataComparisonFilter::MultiChannelImageDataComparisonFilter(): ImageToImageFilter(), + m_Tolerance(0.0f), m_CompareResult(false), m_CompareDetails(NULL) + { + this->SetNumberOfRequiredInputs(2); + } + + MultiChannelImageDataComparisonFilter::~MultiChannelImageDataComparisonFilter() + { + } + + bool MultiChannelImageDataComparisonFilter::GetResult(double threshold) + { + if ( !m_CompareResult ) + { + return false; + } + + if( m_CompareDetails->m_PixelsWithDifference > threshold ) + { + return false; + } + + return true; + } + + void MultiChannelImageDataComparisonFilter::SetValidImage( const Image *_arg ) + { + this->SetInput(0, _arg); + } + + void MultiChannelImageDataComparisonFilter::SetTestImage( const Image *_arg ) + { + this->SetInput(1, _arg); + } + + const Image* MultiChannelImageDataComparisonFilter::GetValidImage() + { + return this->GetInput(0); + } + + const Image* MultiChannelImageDataComparisonFilter::GetTestImage() + { + return this->GetInput(1); + } + + void MultiChannelImageDataComparisonFilter::SetCompareFilterResult( CompareFilterResults* results ) + { + m_CompareDetails = results; + } + + CompareFilterResults* MultiChannelImageDataComparisonFilter::GetCompareFilterResult() + { + return m_CompareDetails; + } + + void MultiChannelImageDataComparisonFilter::GenerateData() + { + // check inputs + const Image* testInput = this->GetTestImage(); + const Image* validInput = this->GetValidImage(); + + + PixelType type = validInput->GetPixelType(); + + if(type.GetComponentType() == itk::ImageIOBase::CHAR) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::UCHAR) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::INT) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::UINT) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::SHORT) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::USHORT) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::LONG) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::ULONG) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::FLOAT) + { + CompareMultiChannelImage( testInput, validInput); + } + else if (type.GetComponentType() == itk::ImageIOBase::DOUBLE) + { + CompareMultiChannelImage( testInput, validInput); + } + else + { + } + + + // Generally this filter is part of the mitk::Image::Equal() method and only checks the equality of the image data + // so no further image type comparison is performed! + // CAVE: If the images differ in a parameter other then the image data, the filter may fail!! + + } + + template + void mitk::MultiChannelImageDataComparisonFilter::CompareMultiChannelImage( const Image* testImage, const Image* validImage ) + { + + unsigned int noOfTimes = validImage->GetDimension(3); + unsigned int noOfPixels = validImage->GetDimension(0)*validImage->GetDimension(1)*validImage->GetDimension(2); + unsigned int noOfComponents = validImage->GetPixelType().GetNumberOfComponents(); + + for( int t = 0; t < noOfTimes; ++t) + { + + ImageReadAccessor readAccTImage(const_cast(testImage), const_cast(testImage)->GetVolumeData(t)); + ImageReadAccessor readAccVImage(const_cast(validImage), const_cast(validImage)->GetVolumeData(t)); + + // #pragma omp parallel for + for( int p = 0; p < noOfPixels*noOfComponents; ++p ) + { + TPixel vDataItem = static_cast(const_cast(readAccVImage.GetData()))[p]; + TPixel tDataItem = static_cast(const_cast(readAccTImage.GetData()))[p]; + + if( tDataItem != vDataItem ) + { + ++m_CompareDetails->m_PixelsWithDifference; + + m_CompareDetails->m_MaximumDifference = std::max(m_CompareDetails->m_MaximumDifference, + std::abs( static_cast(tDataItem - vDataItem) ) ); + + m_CompareDetails->m_MinimumDifference = std::min(m_CompareDetails->m_MinimumDifference, + std::abs( static_cast(tDataItem - vDataItem) )); + + m_CompareDetails->m_TotalDifference += std::abs(static_cast(tDataItem - vDataItem) ); + + } + } + } + m_CompareDetails->m_MeanDifference = m_CompareDetails->m_TotalDifference / m_CompareDetails->m_PixelsWithDifference; + m_CompareDetails->m_PixelsWithDifference /= noOfPixels*noOfComponents*noOfTimes; + + } + +} // end namespace mitk \ No newline at end of file diff --git a/Core/Code/Algorithms/mitkMultiChannelImageDataComparisonFilter.h b/Core/Code/Algorithms/mitkMultiChannelImageDataComparisonFilter.h new file mode 100644 index 0000000000..639c50bbf8 --- /dev/null +++ b/Core/Code/Algorithms/mitkMultiChannelImageDataComparisonFilter.h @@ -0,0 +1,92 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef MITKMULTICHANNELIMAGEDATACOMPARISONFILTER_H +#define MITKMULTICHANNELIMAGEDATACOMPARISONFILTER_H + +// mitk includes +#include "mitkImageToImageFilter.h" +#include "mitkCompareImageDataFilter.h" + +//struct CompareFilterResults; + +namespace mitk +{ + + /*! Documentation: + * \brief Filter for comparing two multi channel mitk::Image objects by channel wise by pixel values + * + * The comparison is channel- / pixel-wise. + */ + class MITK_CORE_EXPORT MultiChannelImageDataComparisonFilter : public ImageToImageFilter + { + public: + + mitkClassMacro(MultiChannelImageDataComparisonFilter, ImageToImageFilter); + itkSimpleNewMacro(Self); + + /*! /brief + */ + void SetTestImage( const Image *_arg); + const Image* GetTestImage(); + + /*! /brief + */ + void SetValidImage( const Image *_arg); + const Image* GetValidImage(); + + /*! /brief Specify the tolerance of the image data comparison + /param Tolerance Default is 0.0f. */ + itkSetMacro(Tolerance, double); + itkGetMacro(Tolerance, double); + + /*! /brief + */ + void SetCompareFilterResult( CompareFilterResults* results); + + /*! /brief Get the detailed results of the comparison run + * /sa CompareFilterResults */ + CompareFilterResults* GetCompareFilterResult(); + + /*! /brief Get the result of the comparison + + * The method compares only the number of pixels with differences. It returns true if the amount + * is under the specified threshold. To get the complete results, use the GetCompareResults method. + + * Returns false also if the itk ComparisionImageFilter raises an exception during update. + + * /param threshold Allowed percentage of pixels with differences (between 0.0...1.0) */ + bool GetResult( double threshold = 0.0f); + + protected: + + MultiChannelImageDataComparisonFilter(); + + ~MultiChannelImageDataComparisonFilter(); + + virtual void GenerateData(); + + template < typename TPixel > + void CompareMultiChannelImage( const Image* testImage, const Image* validImage); + + bool m_CompareResult; + double m_Tolerance; + + CompareFilterResults* m_CompareDetails; + }; +} // end namespace mitk + +#endif // MITKMULTICHANNELIMAGEDATACOMPARISONFILTER_H diff --git a/Core/Code/DataManagement/mitkImage.cpp b/Core/Code/DataManagement/mitkImage.cpp index fee317f520..7448959226 100644 --- a/Core/Code/DataManagement/mitkImage.cpp +++ b/Core/Code/DataManagement/mitkImage.cpp @@ -1,1383 +1,1383 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ //MITK #include "mitkImage.h" #include "mitkImageStatisticsHolder.h" #include "mitkPixelTypeMultiplex.h" #include -#include "mitkCompareImageFilter.h" +#include "mitkCompareImageDataFilter.h" //VTK #include //Other #include #define FILL_C_ARRAY( _arr, _size, _value) for(unsigned int i=0u; i<_size; i++) \ { _arr[i] = _value; } mitk::Image::Image() : m_Dimension(0), m_Dimensions(NULL), m_ImageDescriptor(NULL), m_OffsetTable(NULL), m_CompleteData(NULL), m_ImageStatistics(NULL) { m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS]; FILL_C_ARRAY( m_Dimensions, MAX_IMAGE_DIMENSIONS, 0u); m_Initialized = false; } mitk::Image::Image(const Image &other) : SlicedData(other), m_Dimension(0), m_Dimensions(NULL), m_ImageDescriptor(NULL), m_OffsetTable(NULL), m_CompleteData(NULL), m_ImageStatistics(NULL) { m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS]; FILL_C_ARRAY( m_Dimensions, MAX_IMAGE_DIMENSIONS, 0u); this->Initialize( other.GetPixelType(), other.GetDimension(), other.GetDimensions()); //Since the above called "Initialize" method doesn't take the geometry into account we need to set it //here manually TimeGeometry::Pointer cloned = other.GetTimeGeometry()->Clone(); this->SetTimeGeometry(cloned.GetPointer()); if (this->GetDimension() > 3) { const unsigned int time_steps = this->GetDimension(3); for (unsigned int i = 0u; i < time_steps; ++i) { ImageDataItemPointer volume = const_cast(other).GetVolumeData(i); this->SetVolume(volume->GetData(), i); } } else { ImageDataItemPointer volume = const_cast(other).GetVolumeData(0); this->SetVolume(volume->GetData(), 0); } } mitk::Image::~Image() { Clear(); m_ReferenceCountLock.Lock(); m_ReferenceCount = 3; m_ReferenceCountLock.Unlock(); m_ReferenceCountLock.Lock(); m_ReferenceCount = 0; m_ReferenceCountLock.Unlock(); if(m_OffsetTable != NULL) delete [] m_OffsetTable; if(m_ImageStatistics != NULL) delete m_ImageStatistics; } const mitk::PixelType mitk::Image::GetPixelType(int n) const { return this->m_ImageDescriptor->GetChannelTypeById(n); } unsigned int mitk::Image::GetDimension() const { return m_Dimension; } unsigned int mitk::Image::GetDimension(int i) const { if((i>=0) && (i<(int)m_Dimension)) return m_Dimensions[i]; return 1; } void* mitk::Image::GetData() { if(m_Initialized==false) { if(GetSource().IsNull()) return NULL; if(GetSource()->Updating()==false) GetSource()->UpdateOutputInformation(); } m_CompleteData=GetChannelData(); // update channel's data // if data was not available at creation point, the m_Data of channel descriptor is NULL // if data present, it won't be overwritten m_ImageDescriptor->GetChannelDescriptor(0).SetData(m_CompleteData->GetData()); return m_CompleteData->GetData(); } template void AccessPixel( const mitk::PixelType ptype, void* data, const unsigned int offset, double& value ) { value = 0.0; if( data == NULL ) return; if(ptype.GetBpe() != 24) { value = (double) (((T*) data)[ offset ]); } else { const unsigned int rgboffset = 3 * offset; double returnvalue = (((T*) data)[rgboffset ]); returnvalue += (((T*) data)[rgboffset + 1]); returnvalue += (((T*) data)[rgboffset + 2]); value = returnvalue; } } double mitk::Image::GetPixelValueByIndex(const mitk::Index3D &position, unsigned int timestep) { double value = 0; if (this->GetTimeSteps() < timestep) { timestep = this->GetTimeSteps(); } value = 0.0; const unsigned int* imageDims = this->m_ImageDescriptor->GetDimensions(); const mitk::PixelType ptype = this->m_ImageDescriptor->GetChannelTypeById(0); // Comparison ?>=0 not needed since all position[i] and timestep are unsigned int // (position[0]>=0 && position[1] >=0 && position[2]>=0 && timestep>=0) // bug-11978 : we still need to catch index with negative values if ( position[0] < 0 || position[1] < 0 || position[2] < 0 ) { MITK_WARN << "Given position ("<< position << ") is out of image range, returning 0." ; } // check if the given position is inside the index range of the image, the 3rd dimension needs to be compared only if the dimension is not 0 else if ( (unsigned int)position[0] >= imageDims[0] || (unsigned int)position[1] >= imageDims[1] || ( imageDims[2] && (unsigned int)position[2] >= imageDims[2] )) { MITK_WARN << "Given position ("<< position << ") is out of image range, returning 0." ; } else { const unsigned int offset = position[0] + position[1]*imageDims[0] + position[2]*imageDims[0]*imageDims[1] + timestep*imageDims[0]*imageDims[1]*imageDims[2]; mitkPixelTypeMultiplex3( AccessPixel, ptype, this->GetData(), offset, value ); } return value; } double mitk::Image::GetPixelValueByWorldCoordinate(const mitk::Point3D& position, unsigned int timestep) { double value = 0.0; if (this->GetTimeSteps() < timestep) { timestep = this->GetTimeSteps(); } Index3D itkIndex; this->GetGeometry()->WorldToIndex(position, itkIndex); value = this->GetPixelValueByIndex( itkIndex, timestep); return value; } mitk::ImageVtkAccessor* mitk::Image::GetVtkImageData(int t, int n) { if(m_Initialized==false) { if(GetSource().IsNull()) return NULL; if(GetSource()->Updating()==false) GetSource()->UpdateOutputInformation(); } ImageDataItemPointer volume=GetVolumeData(t, n); if(volume.GetPointer()==NULL || volume->GetVtkImageData(this) == NULL) return NULL; SlicedGeometry3D* geom3d = GetSlicedGeometry(t); float *fspacing = const_cast(geom3d->GetFloatSpacing()); double dspacing[3] = {fspacing[0],fspacing[1],fspacing[2]}; volume->GetVtkImageData(this)->SetSpacing( dspacing ); return volume->GetVtkImageData(this); } mitk::Image::ImageDataItemPointer mitk::Image::GetSliceData(int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) { if(IsValidSlice(s,t,n)==false) return NULL; const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); // slice directly available? int pos=GetSliceIndex(s,t,n); if(m_Slices[pos].GetPointer()!=NULL) return m_Slices[pos]; // is slice available as part of a volume that is available? ImageDataItemPointer sl, ch, vol; vol=m_Volumes[GetVolumeIndex(t,n)]; if((vol.GetPointer()!=NULL) && (vol->IsComplete())) { sl=new ImageDataItem(*vol, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(ptypeSize)); sl->SetComplete(true); return m_Slices[pos]=sl; } // is slice available as part of a channel that is available? ch=m_Channels[n]; if((ch.GetPointer()!=NULL) && (ch->IsComplete())) { sl=new ImageDataItem(*ch, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, (((size_t) s)*m_OffsetTable[2]+((size_t) t)*m_OffsetTable[3])*(ptypeSize)); sl->SetComplete(true); return m_Slices[pos]=sl; } // slice is unavailable. Can we calculate it? if((GetSource().IsNotNull()) && (GetSource()->Updating()==false)) { // ... wir mussen rechnen!!! .... m_RequestedRegion.SetIndex(0, 0); m_RequestedRegion.SetIndex(1, 0); m_RequestedRegion.SetIndex(2, s); m_RequestedRegion.SetIndex(3, t); m_RequestedRegion.SetIndex(4, n); m_RequestedRegion.SetSize(0, m_Dimensions[0]); m_RequestedRegion.SetSize(1, m_Dimensions[1]); m_RequestedRegion.SetSize(2, 1); m_RequestedRegion.SetSize(3, 1); m_RequestedRegion.SetSize(4, 1); m_RequestedRegionInitialized=true; GetSource()->Update(); if(IsSliceSet(s,t,n)) //yes: now we can call ourselves without the risk of a endless loop (see "if" above) return GetSliceData(s,t,n,data,importMemoryManagement); else return NULL; } else { ImageDataItemPointer item = AllocateSliceData(s,t,n,data,importMemoryManagement); item->SetComplete(true); return item; } } mitk::Image::ImageDataItemPointer mitk::Image::GetVolumeData(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) { if(IsValidVolume(t,n)==false) return NULL; ImageDataItemPointer ch, vol; // volume directly available? int pos=GetVolumeIndex(t,n); vol=m_Volumes[pos]; if((vol.GetPointer()!=NULL) && (vol->IsComplete())) return vol; const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); // is volume available as part of a channel that is available? ch=m_Channels[n]; if((ch.GetPointer()!=NULL) && (ch->IsComplete())) { vol=new ImageDataItem(*ch, m_ImageDescriptor, 3, data, importMemoryManagement == ManageMemory, (((size_t) t)*m_OffsetTable[3])*(ptypeSize)); vol->SetComplete(true); return m_Volumes[pos]=vol; } // let's see if all slices of the volume are set, so that we can (could) combine them to a volume bool complete=true; unsigned int s; for(s=0;sSetComplete(true); } else { mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(n); vol=m_Volumes[pos]; // ok, let's combine the slices! if(vol.GetPointer()==NULL) vol=new ImageDataItem( chPixelType, 3, m_Dimensions, NULL, true); vol->SetComplete(true); size_t size=m_OffsetTable[2]*(ptypeSize); for(s=0;sGetParent()!=vol) { // copy data of slices in volume size_t offset = ((size_t) s)*size; std::memcpy(static_cast(vol->GetData())+offset, sl->GetData(), size); // FIXME mitkIpPicDescriptor * pic = sl->GetPicDescriptor(); // replace old slice with reference to volume sl=new ImageDataItem(*vol, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*size); sl->SetComplete(true); //mitkIpFuncCopyTags(sl->GetPicDescriptor(), pic); m_Slices[posSl]=sl; } } //if(vol->GetPicDescriptor()->info->tags_head==NULL) // mitkIpFuncCopyTags(vol->GetPicDescriptor(), m_Slices[GetSliceIndex(0,t,n)]->GetPicDescriptor()); } return m_Volumes[pos]=vol; } // volume is unavailable. Can we calculate it? if((GetSource().IsNotNull()) && (GetSource()->Updating()==false)) { // ... wir muessen rechnen!!! .... m_RequestedRegion.SetIndex(0, 0); m_RequestedRegion.SetIndex(1, 0); m_RequestedRegion.SetIndex(2, 0); m_RequestedRegion.SetIndex(3, t); m_RequestedRegion.SetIndex(4, n); m_RequestedRegion.SetSize(0, m_Dimensions[0]); m_RequestedRegion.SetSize(1, m_Dimensions[1]); m_RequestedRegion.SetSize(2, m_Dimensions[2]); m_RequestedRegion.SetSize(3, 1); m_RequestedRegion.SetSize(4, 1); m_RequestedRegionInitialized=true; GetSource()->Update(); if(IsVolumeSet(t,n)) //yes: now we can call ourselves without the risk of a endless loop (see "if" above) return GetVolumeData(t,n,data,importMemoryManagement); else return NULL; } else { ImageDataItemPointer item = AllocateVolumeData(t,n,data,importMemoryManagement); item->SetComplete(true); return item; } } mitk::Image::ImageDataItemPointer mitk::Image::GetChannelData(int n, void *data, ImportMemoryManagementType importMemoryManagement) { if(IsValidChannel(n)==false) return NULL; ImageDataItemPointer ch, vol; ch=m_Channels[n]; if((ch.GetPointer()!=NULL) && (ch->IsComplete())) return ch; // let's see if all volumes are set, so that we can (could) combine them to a channel if(IsChannelSet(n)) { // if there is only one time frame we do not need to combine anything if(m_Dimensions[3]<=1) { vol=GetVolumeData(0,n,data,importMemoryManagement); ch=new ImageDataItem(*vol, m_ImageDescriptor, m_ImageDescriptor->GetNumberOfDimensions(), data, importMemoryManagement == ManageMemory); ch->SetComplete(true); } else { const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ch=m_Channels[n]; // ok, let's combine the volumes! if(ch.GetPointer()==NULL) ch=new ImageDataItem(this->m_ImageDescriptor, NULL, true); ch->SetComplete(true); size_t size=m_OffsetTable[m_Dimension-1]*(ptypeSize); unsigned int t; ImageDataItemPointerArray::iterator slicesIt = m_Slices.begin()+n*m_Dimensions[2]*m_Dimensions[3]; for(t=0;tGetParent()!=ch) { // copy data of volume in channel size_t offset = ((size_t) t)*m_OffsetTable[3]*(ptypeSize); std::memcpy(static_cast(ch->GetData())+offset, vol->GetData(), size); // REVEIW FIX mitkIpPicDescriptor * pic = vol->GetPicDescriptor(); // replace old volume with reference to channel vol=new ImageDataItem(*ch, m_ImageDescriptor, 3, data, importMemoryManagement == ManageMemory, offset); vol->SetComplete(true); //mitkIpFuncCopyTags(vol->GetPicDescriptor(), pic); m_Volumes[posVol]=vol; // get rid of slices - they may point to old volume ImageDataItemPointer dnull=NULL; for(unsigned int i = 0; i < m_Dimensions[2]; ++i, ++slicesIt) { assert(slicesIt != m_Slices.end()); *slicesIt = dnull; } } } // REVIEW FIX // if(ch->GetPicDescriptor()->info->tags_head==NULL) // mitkIpFuncCopyTags(ch->GetPicDescriptor(), m_Volumes[GetVolumeIndex(0,n)]->GetPicDescriptor()); } return m_Channels[n]=ch; } // channel is unavailable. Can we calculate it? if((GetSource().IsNotNull()) && (GetSource()->Updating()==false)) { // ... wir muessen rechnen!!! .... m_RequestedRegion.SetIndex(0, 0); m_RequestedRegion.SetIndex(1, 0); m_RequestedRegion.SetIndex(2, 0); m_RequestedRegion.SetIndex(3, 0); m_RequestedRegion.SetIndex(4, n); m_RequestedRegion.SetSize(0, m_Dimensions[0]); m_RequestedRegion.SetSize(1, m_Dimensions[1]); m_RequestedRegion.SetSize(2, m_Dimensions[2]); m_RequestedRegion.SetSize(3, m_Dimensions[3]); m_RequestedRegion.SetSize(4, 1); m_RequestedRegionInitialized=true; GetSource()->Update(); // did it work? if(IsChannelSet(n)) //yes: now we can call ourselves without the risk of a endless loop (see "if" above) return GetChannelData(n,data,importMemoryManagement); else return NULL; } else { ImageDataItemPointer item = AllocateChannelData(n,data,importMemoryManagement); item->SetComplete(true); return item; } } bool mitk::Image::IsSliceSet(int s, int t, int n) const { if(IsValidSlice(s,t,n)==false) return false; if(m_Slices[GetSliceIndex(s,t,n)].GetPointer()!=NULL) return true; ImageDataItemPointer ch, vol; vol=m_Volumes[GetVolumeIndex(t,n)]; if((vol.GetPointer()!=NULL) && (vol->IsComplete())) return true; ch=m_Channels[n]; if((ch.GetPointer()!=NULL) && (ch->IsComplete())) return true; return false; } bool mitk::Image::IsVolumeSet(int t, int n) const { if(IsValidVolume(t,n)==false) return false; ImageDataItemPointer ch, vol; // volume directly available? vol=m_Volumes[GetVolumeIndex(t,n)]; if((vol.GetPointer()!=NULL) && (vol->IsComplete())) return true; // is volume available as part of a channel that is available? ch=m_Channels[n]; if((ch.GetPointer()!=NULL) && (ch->IsComplete())) return true; // let's see if all slices of the volume are set, so that we can (could) combine them to a volume unsigned int s; for(s=0;sIsComplete())) return true; // let's see if all volumes are set, so that we can (could) combine them to a channel unsigned int t; for(t=0;t(data), s, t, n, CopyMemory); } bool mitk::Image::SetVolume(const void *data, int t, int n) { // const_cast is no risk for ImportMemoryManagementType == CopyMemory return SetImportVolume(const_cast(data), t, n, CopyMemory); } bool mitk::Image::SetChannel(const void *data, int n) { // const_cast is no risk for ImportMemoryManagementType == CopyMemory return SetImportChannel(const_cast(data), n, CopyMemory); } bool mitk::Image::SetImportSlice(void *data, int s, int t, int n, ImportMemoryManagementType importMemoryManagement) { if(IsValidSlice(s,t,n)==false) return false; ImageDataItemPointer sl; const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); if(IsSliceSet(s,t,n)) { sl=GetSliceData(s,t,n,data,importMemoryManagement); if(sl->GetManageMemory()==false) { sl=AllocateSliceData(s,t,n,data,importMemoryManagement); if(sl.GetPointer()==NULL) return false; } if ( sl->GetData() != data ) std::memcpy(sl->GetData(), data, m_OffsetTable[2]*(ptypeSize)); sl->Modified(); //we have changed the data: call Modified()! Modified(); } else { sl=AllocateSliceData(s,t,n,data,importMemoryManagement); if(sl.GetPointer()==NULL) return false; if ( sl->GetData() != data ) std::memcpy(sl->GetData(), data, m_OffsetTable[2]*(ptypeSize)); //we just added a missing slice, which is not regarded as modification. //Therefore, we do not call Modified()! } return true; } bool mitk::Image::SetImportVolume(void *data, int t, int n, ImportMemoryManagementType importMemoryManagement) { if(IsValidVolume(t,n)==false) return false; const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ImageDataItemPointer vol; if(IsVolumeSet(t,n)) { vol=GetVolumeData(t,n,data,importMemoryManagement); if(vol->GetManageMemory()==false) { vol=AllocateVolumeData(t,n,data,importMemoryManagement); if(vol.GetPointer()==NULL) return false; } if ( vol->GetData() != data ) std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(ptypeSize)); vol->Modified(); vol->SetComplete(true); //we have changed the data: call Modified()! Modified(); } else { vol=AllocateVolumeData(t,n,data,importMemoryManagement); if(vol.GetPointer()==NULL) return false; if ( vol->GetData() != data ) { std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(ptypeSize)); } vol->SetComplete(true); this->m_ImageDescriptor->GetChannelDescriptor(n).SetData( vol->GetData() ); //we just added a missing Volume, which is not regarded as modification. //Therefore, we do not call Modified()! } return true; } bool mitk::Image::SetImportChannel(void *data, int n, ImportMemoryManagementType importMemoryManagement) { if(IsValidChannel(n)==false) return false; // channel descriptor const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ImageDataItemPointer ch; if(IsChannelSet(n)) { ch=GetChannelData(n,data,importMemoryManagement); if(ch->GetManageMemory()==false) { ch=AllocateChannelData(n,data,importMemoryManagement); if(ch.GetPointer()==NULL) return false; } if ( ch->GetData() != data ) std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(ptypeSize)); ch->Modified(); ch->SetComplete(true); //we have changed the data: call Modified()! Modified(); } else { ch=AllocateChannelData(n,data,importMemoryManagement); if(ch.GetPointer()==NULL) return false; if ( ch->GetData() != data ) std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(ptypeSize)); ch->SetComplete(true); this->m_ImageDescriptor->GetChannelDescriptor(n).SetData( ch->GetData() ); //we just added a missing Channel, which is not regarded as modification. //Therefore, we do not call Modified()! } return true; } void mitk::Image::Initialize() { ImageDataItemPointerArray::iterator it, end; for( it=m_Slices.begin(), end=m_Slices.end(); it!=end; ++it ) { (*it)=NULL; } for( it=m_Volumes.begin(), end=m_Volumes.end(); it!=end; ++it ) { (*it)=NULL; } for( it=m_Channels.begin(), end=m_Channels.end(); it!=end; ++it ) { (*it)=NULL; } m_CompleteData = NULL; if( m_ImageStatistics == NULL) { m_ImageStatistics = new mitk::ImageStatisticsHolder( this ); } SetRequestedRegionToLargestPossibleRegion(); } void mitk::Image::Initialize(const mitk::ImageDescriptor::Pointer inDesc) { // store the descriptor this->m_ImageDescriptor = inDesc; // initialize image this->Initialize( inDesc->GetChannelDescriptor(0).GetPixelType(), inDesc->GetNumberOfDimensions(), inDesc->GetDimensions(), 1 ); } void mitk::Image::Initialize(const mitk::PixelType& type, unsigned int dimension, const unsigned int *dimensions, unsigned int channels) { Clear(); m_Dimension=dimension; if(!dimensions) itkExceptionMacro(<< "invalid zero dimension image"); unsigned int i; for(i=0;im_ImageDescriptor = mitk::ImageDescriptor::New(); this->m_ImageDescriptor->Initialize( this->m_Dimensions, this->m_Dimension ); for(i=0;i<4;++i) { m_LargestPossibleRegion.SetIndex(i, 0); m_LargestPossibleRegion.SetSize (i, m_Dimensions[i]); } m_LargestPossibleRegion.SetIndex(i, 0); m_LargestPossibleRegion.SetSize(i, channels); if(m_LargestPossibleRegion.GetNumberOfPixels()==0) { delete [] m_Dimensions; m_Dimensions = NULL; return; } for( unsigned int i=0u; im_ImageDescriptor->AddNewChannel( type ); } PlaneGeometry::Pointer planegeometry = PlaneGeometry::New(); planegeometry->InitializeStandardPlane(m_Dimensions[0], m_Dimensions[1]); SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New(); slicedGeometry->InitializeEvenlySpaced(planegeometry, m_Dimensions[2]); if(dimension>=4) { TimeBounds timebounds; timebounds[0] = 0.0; timebounds[1] = 1.0; slicedGeometry->SetTimeBounds(timebounds); } ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]); for (TimeStepType step = 0; step < timeGeometry->CountTimeSteps(); ++step) { timeGeometry->GetGeometryForTimeStep(step)->ImageGeometryOn(); } SetTimeGeometry(timeGeometry); ImageDataItemPointer dnull=NULL; m_Channels.assign(GetNumberOfChannels(), dnull); m_Volumes.assign(GetNumberOfChannels()*m_Dimensions[3], dnull); m_Slices.assign(GetNumberOfChannels()*m_Dimensions[3]*m_Dimensions[2], dnull); ComputeOffsetTable(); Initialize(); m_Initialized = true; } void mitk::Image::Initialize(const mitk::PixelType& type, const mitk::Geometry3D& geometry, unsigned int channels, int tDim ) { mitk::ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); Geometry3D::Pointer geometry3D = geometry.Clone(); timeGeometry->Initialize(geometry3D.GetPointer(), tDim); this->Initialize(type, *timeGeometry, channels, tDim); } void mitk::Image::Initialize(const mitk::PixelType& type, const mitk::TimeGeometry& geometry, unsigned int channels, int tDim ) { unsigned int dimensions[5]; dimensions[0] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(0)+0.5); dimensions[1] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(1)+0.5); dimensions[2] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(2)+0.5); dimensions[3] = (tDim > 0) ? tDim : geometry.CountTimeSteps(); dimensions[4] = 0; unsigned int dimension = 2; if ( dimensions[2] > 1 ) dimension = 3; if ( dimensions[3] > 1 ) dimension = 4; Initialize( type, dimension, dimensions, channels ); if (geometry.CountTimeSteps() > 1) { TimeGeometry::Pointer cloned = geometry.Clone(); SetTimeGeometry(cloned.GetPointer()); } else Superclass::SetGeometry(geometry.GetGeometryForTimeStep(0)); /* //Old //TODO_GOETZ Really necessary? mitk::BoundingBox::BoundsArrayType bounds = geometry.GetBoundingBoxInWorld()->GetBounds(); if( (bounds[0] != 0.0) || (bounds[2] != 0.0) || (bounds[4] != 0.0) ) { SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0); mitk::Point3D origin; origin.Fill(0.0); slicedGeometry->IndexToWorld(origin, origin); bounds[1]-=bounds[0]; bounds[3]-=bounds[2]; bounds[5]-=bounds[4]; bounds[0] = 0.0; bounds[2] = 0.0; bounds[4] = 0.0; this->m_ImageDescriptor->Initialize( this->m_Dimensions, this->m_Dimension ); slicedGeometry->SetBounds(bounds); slicedGeometry->GetIndexToWorldTransform()->SetOffset(origin.GetVnlVector().data_block()); ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]); SetTimeGeometry(timeGeometry); }*/ } void mitk::Image::Initialize(const mitk::PixelType& type, int sDim, const mitk::Geometry2D& geometry2d, bool flipped, unsigned int channels, int tDim ) { SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New(); slicedGeometry->InitializeEvenlySpaced(static_cast(geometry2d.Clone().GetPointer()), sDim, flipped); Initialize(type, *slicedGeometry, channels, tDim); } void mitk::Image::Initialize(const mitk::Image* image) { Initialize(image->GetPixelType(), *image->GetTimeGeometry()); } void mitk::Image::Initialize(vtkImageData* vtkimagedata, int channels, int tDim, int sDim, int pDim) { if(vtkimagedata==NULL) return; m_Dimension=vtkimagedata->GetDataDimension(); unsigned int i, *tmpDimensions=new unsigned int[m_Dimension>4?m_Dimension:4]; for(i=0;iGetDimensions()[i]; if(m_Dimension<4) { unsigned int *p; for(i=0,p=tmpDimensions+m_Dimension;i<4-m_Dimension;++i, ++p) *p=1; } if(pDim>=0) { tmpDimensions[1]=pDim; if(m_Dimension < 2) m_Dimension = 2; } if(sDim>=0) { tmpDimensions[2]=sDim; if(m_Dimension < 3) m_Dimension = 3; } if(tDim>=0) { tmpDimensions[3]=tDim; if(m_Dimension < 4) m_Dimension = 4; } switch ( vtkimagedata->GetScalarType() ) { case VTK_BIT: case VTK_CHAR: //pixelType.Initialize(typeid(char), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_UNSIGNED_CHAR: //pixelType.Initialize(typeid(unsigned char), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_SHORT: //pixelType.Initialize(typeid(short), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_UNSIGNED_SHORT: //pixelType.Initialize(typeid(unsigned short), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_INT: //pixelType.Initialize(typeid(int), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_UNSIGNED_INT: //pixelType.Initialize(typeid(unsigned int), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_LONG: //pixelType.Initialize(typeid(long), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_UNSIGNED_LONG: //pixelType.Initialize(typeid(unsigned long), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_FLOAT: //pixelType.Initialize(typeid(float), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; case VTK_DOUBLE: //pixelType.Initialize(typeid(double), vtkimagedata->GetNumberOfScalarComponents()); Initialize(mitk::MakeScalarPixelType(), m_Dimension, tmpDimensions, channels); break; default: break; } /* Initialize(pixelType, m_Dimension, tmpDimensions, channels); */ const double *spacinglist = vtkimagedata->GetSpacing(); Vector3D spacing; FillVector3D(spacing, spacinglist[0], 1.0, 1.0); if(m_Dimension>=2) spacing[1]=spacinglist[1]; if(m_Dimension>=3) spacing[2]=spacinglist[2]; // access origin of vtkImage Point3D origin; vtkFloatingPointType vtkorigin[3]; vtkimagedata->GetOrigin(vtkorigin); FillVector3D(origin, vtkorigin[0], 0.0, 0.0); if(m_Dimension>=2) origin[1]=vtkorigin[1]; if(m_Dimension>=3) origin[2]=vtkorigin[2]; SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0); // re-initialize PlaneGeometry with origin and direction PlaneGeometry* planeGeometry = static_cast(slicedGeometry->GetGeometry2D(0)); planeGeometry->SetOrigin(origin); // re-initialize SlicedGeometry3D slicedGeometry->SetOrigin(origin); slicedGeometry->SetSpacing(spacing); ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]); SetTimeGeometry(timeGeometry); delete [] tmpDimensions; } bool mitk::Image::IsValidSlice(int s, int t, int n) const { if(m_Initialized) return ((s>=0) && (s<(int)m_Dimensions[2]) && (t>=0) && (t< (int) m_Dimensions[3]) && (n>=0) && (n< (int)GetNumberOfChannels())); else return false; } bool mitk::Image::IsValidVolume(int t, int n) const { if(m_Initialized) return IsValidSlice(0, t, n); else return false; } bool mitk::Image::IsValidChannel(int n) const { if(m_Initialized) return IsValidSlice(0, 0, n); else return false; } void mitk::Image::ComputeOffsetTable() { if(m_OffsetTable!=NULL) delete [] m_OffsetTable; m_OffsetTable=new size_t[m_Dimension>4 ? m_Dimension+1 : 4+1]; unsigned int i; size_t num=1; m_OffsetTable[0] = 1; for (i=0; i < m_Dimension; ++i) { num *= m_Dimensions[i]; m_OffsetTable[i+1] = num; } for (;i < 4; ++i) m_OffsetTable[i+1] = num; } bool mitk::Image::IsValidTimeStep(int t) const { return ( ( m_Dimension >= 4 && t <= (int)m_Dimensions[3] && t > 0 ) || (t == 0) ); } void mitk::Image::Expand(unsigned int timeSteps) { if(timeSteps < 1) itkExceptionMacro(<< "Invalid timestep in Image!"); Superclass::Expand(timeSteps); } int mitk::Image::GetSliceIndex(int s, int t, int n) const { if(IsValidSlice(s,t,n)==false) return false; return ((size_t)s)+((size_t) t)*m_Dimensions[2]+((size_t) n)*m_Dimensions[3]*m_Dimensions[2]; //?? } int mitk::Image::GetVolumeIndex(int t, int n) const { if(IsValidVolume(t,n)==false) return false; return ((size_t)t)+((size_t) n)*m_Dimensions[3]; //?? } mitk::Image::ImageDataItemPointer mitk::Image::AllocateSliceData(int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) { int pos; pos=GetSliceIndex(s,t,n); const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); // is slice available as part of a volume that is available? ImageDataItemPointer sl, ch, vol; vol=m_Volumes[GetVolumeIndex(t,n)]; if(vol.GetPointer()!=NULL) { sl=new ImageDataItem(*vol, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(ptypeSize)); sl->SetComplete(true); return m_Slices[pos]=sl; } // is slice available as part of a channel that is available? ch=m_Channels[n]; if(ch.GetPointer()!=NULL) { sl=new ImageDataItem(*ch, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, (((size_t) s)*m_OffsetTable[2]+((size_t) t)*m_OffsetTable[3])*(ptypeSize)); sl->SetComplete(true); return m_Slices[pos]=sl; } // allocate new volume (instead of a single slice to keep data together!) m_Volumes[GetVolumeIndex(t,n)]=vol=AllocateVolumeData(t,n,NULL,importMemoryManagement); sl=new ImageDataItem(*vol, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(ptypeSize)); sl->SetComplete(true); return m_Slices[pos]=sl; ////ALTERNATIVE: //// allocate new slice //sl=new ImageDataItem(*m_PixelType, 2, m_Dimensions); //m_Slices[pos]=sl; //return vol; } mitk::Image::ImageDataItemPointer mitk::Image::AllocateVolumeData(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) { int pos; pos=GetVolumeIndex(t,n); const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); // is volume available as part of a channel that is available? ImageDataItemPointer ch, vol; ch=m_Channels[n]; if(ch.GetPointer()!=NULL) { vol=new ImageDataItem(*ch, m_ImageDescriptor, 3, data,importMemoryManagement == ManageMemory, (((size_t) t)*m_OffsetTable[3])*(ptypeSize)); return m_Volumes[pos]=vol; } mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(n); // allocate new volume if(importMemoryManagement == CopyMemory) { vol=new ImageDataItem( chPixelType, 3, m_Dimensions, NULL, true); if(data != NULL) std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(ptypeSize)); } else { vol=new ImageDataItem( chPixelType, 3, m_Dimensions, data, importMemoryManagement == ManageMemory); } m_Volumes[pos]=vol; return vol; } mitk::Image::ImageDataItemPointer mitk::Image::AllocateChannelData(int n, void *data, ImportMemoryManagementType importMemoryManagement) { ImageDataItemPointer ch; // allocate new channel if(importMemoryManagement == CopyMemory) { const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ch=new ImageDataItem(this->m_ImageDescriptor, NULL, true); if(data != NULL) std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(ptypeSize)); } else { ch=new ImageDataItem(this->m_ImageDescriptor, data, importMemoryManagement == ManageMemory); } m_Channels[n]=ch; return ch; } unsigned int* mitk::Image::GetDimensions() const { return m_Dimensions; } void mitk::Image::Clear() { Superclass::Clear(); delete [] m_Dimensions; m_Dimensions = NULL; } void mitk::Image::SetGeometry(Geometry3D* aGeometry3D) { // Please be aware of the 0.5 offset/pixel-center issue! See Geometry documentation for further information if(aGeometry3D->GetImageGeometry()==false) { MITK_INFO << "WARNING: Applied a non-image geometry onto an image. Please be SURE that this geometry is pixel-center-based! If it is not, you need to call Geometry3D->ChangeImageGeometryConsideringOriginOffset(true) before calling image->setGeometry(..)\n"; } Superclass::SetGeometry(aGeometry3D); for (TimeStepType step = 0; step < GetTimeGeometry()->CountTimeSteps(); ++step) GetTimeGeometry()->GetGeometryForTimeStep(step)->ImageGeometryOn(); } void mitk::Image::PrintSelf(std::ostream& os, itk::Indent indent) const { unsigned char i; if(m_Initialized) { os << indent << " Dimension: " << m_Dimension << std::endl; os << indent << " Dimensions: "; for(i=0; i < m_Dimension; ++i) os << GetDimension(i) << " "; os << std::endl; for(unsigned int ch=0; ch < this->m_ImageDescriptor->GetNumberOfChannels(); ch++) { mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(ch); os << indent << " Channel: " << this->m_ImageDescriptor->GetChannelName(ch) << std::endl; os << indent << " PixelType: " << chPixelType.GetPixelTypeAsString() << std::endl; os << indent << " BytesPerElement: " << chPixelType.GetSize() << std::endl; os << indent << " ComponentType: " << chPixelType.GetComponentTypeAsString() << std::endl; os << indent << " NumberOfComponents: " << chPixelType.GetNumberOfComponents() << std::endl; os << indent << " BitsPerComponent: " << chPixelType.GetBitsPerComponent() << std::endl; } } else { os << indent << " Image not initialized: m_Initialized: false" << std::endl; } Superclass::PrintSelf(os,indent); } bool mitk::Image::IsRotated() const { const mitk::Geometry3D* geo = this->GetGeometry(); bool ret = false; if(geo) { const vnl_matrix_fixed & mx = geo->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix(); float ref = 0; for(short k = 0; k < 3; ++k) ref += mx[k][k]; ref/=1000; // Arbitrary value; if a non-diagonal (nd) element is bigger then this, matrix is considered nd. for(short i = 0; i < 3; ++i) { for(short j = 0; j < 3; ++j) { if(i != j) { if(std::abs(mx[i][j]) > ref) // matrix is nd ret = true; } } } } return ret; } mitk::ScalarType mitk::Image::GetScalarValueMin(int t) const { return m_ImageStatistics->GetScalarValueMin(t); } //## \brief Get the maximum for scalar images mitk::ScalarType mitk::Image::GetScalarValueMax(int t) const { return m_ImageStatistics->GetScalarValueMax(t); } //## \brief Get the second smallest value for scalar images mitk::ScalarType mitk::Image::GetScalarValue2ndMin(int t) const { return m_ImageStatistics->GetScalarValue2ndMin(t); } mitk::ScalarType mitk::Image::GetScalarValueMinNoRecompute( unsigned int t ) const { return m_ImageStatistics->GetScalarValueMinNoRecompute(t); } mitk::ScalarType mitk::Image::GetScalarValue2ndMinNoRecompute( unsigned int t ) const { return m_ImageStatistics->GetScalarValue2ndMinNoRecompute(t); } mitk::ScalarType mitk::Image::GetScalarValue2ndMax(int t) const { return m_ImageStatistics->GetScalarValue2ndMax(t); } mitk::ScalarType mitk::Image::GetScalarValueMaxNoRecompute( unsigned int t) const { return m_ImageStatistics->GetScalarValueMaxNoRecompute(t); } mitk::ScalarType mitk::Image::GetScalarValue2ndMaxNoRecompute( unsigned int t ) const { return m_ImageStatistics->GetScalarValue2ndMaxNoRecompute(t); } mitk::ScalarType mitk::Image::GetCountOfMinValuedVoxels(int t ) const { return m_ImageStatistics->GetCountOfMinValuedVoxels(t); } mitk::ScalarType mitk::Image::GetCountOfMaxValuedVoxels(int t) const { return m_ImageStatistics->GetCountOfMaxValuedVoxels(t); } unsigned int mitk::Image::GetCountOfMaxValuedVoxelsNoRecompute( unsigned int t ) const { return m_ImageStatistics->GetCountOfMaxValuedVoxelsNoRecompute(t); } unsigned int mitk::Image::GetCountOfMinValuedVoxelsNoRecompute( unsigned int t ) const { return m_ImageStatistics->GetCountOfMinValuedVoxelsNoRecompute(t); } bool mitk::Equal(const mitk::Image* rightHandSide, const mitk::Image* leftHandSide, ScalarType eps, bool verbose) { bool returnValue = true; if( rightHandSide == NULL ) { if(verbose) MITK_INFO << "[( Image )] rightHandSide is NULL."; return false; } if( leftHandSide == NULL ) { if(verbose) MITK_INFO << "[( Image )] leftHandSide is NULL."; return false; } // Dimensionality if( rightHandSide->GetDimension() != leftHandSide->GetDimension() ) { if(verbose) { MITK_INFO << "[( Image )] Dimensionality differs."; MITK_INFO << "rightHandSide is " << rightHandSide->GetDimension() << "leftHandSide is " << leftHandSide->GetDimension(); } returnValue = false; } // Pair-wise dimension (size) comparison unsigned int minDimensionality = std::min(rightHandSide->GetDimension(),leftHandSide->GetDimension()); for( unsigned int i=0; i< minDimensionality; ++i) { if( rightHandSide->GetDimension(i) != leftHandSide->GetDimension(i) ) { returnValue = false; if(verbose) { MITK_INFO << "[( Image )] dimension differs."; MITK_INFO << "rightHandSide->GetDimension("<GetDimension(i) << "leftHandSide->GetDimension("<GetDimension(i); } } } // Pixeltype mitk::PixelType pixelTypeRightHandSide = rightHandSide->GetPixelType(); mitk::PixelType pixelTypeLeftHandSide = leftHandSide->GetPixelType(); if( !( pixelTypeRightHandSide == pixelTypeLeftHandSide ) ) { if(verbose) { MITK_INFO << "[( Image )] PixelType differs."; MITK_INFO << "rightHandSide is " << pixelTypeRightHandSide.GetTypeAsString() << "leftHandSide is " << pixelTypeLeftHandSide.GetTypeAsString(); } returnValue = false; } // Geometries if( !mitk::Equal( leftHandSide->GetGeometry(), rightHandSide->GetGeometry(), eps, verbose) ) { if(verbose) { MITK_INFO << "[( Image )] Geometries differ."; } returnValue = false; } // Pixel values - default mode [ 0 threshold in difference ] // compare only if all previous checks were successfull, otherwise the ITK filter will throw an exception if( returnValue ) { - mitk::CompareImageFilter::Pointer compareFilter = mitk::CompareImageFilter::New(); + mitk::CompareImageDataFilter::Pointer compareFilter = mitk::CompareImageDataFilter::New(); compareFilter->SetInput(0, rightHandSide); compareFilter->SetInput(1, leftHandSide); compareFilter->Update(); if(( !compareFilter->GetResult() ) ) { returnValue = false; if(verbose) { MITK_INFO << "[(Image)] Pixel values differ: "; } compareFilter->GetCompareResults().PrintSelf(); } } return returnValue; } diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index 73f6320348..84442734cb 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,399 +1,400 @@ set(H_FILES Algorithms/itkImportMitkImageContainer.h Algorithms/itkImportMitkImageContainer.txx Algorithms/itkLocalVariationImageFilter.h Algorithms/itkLocalVariationImageFilter.txx Algorithms/itkMITKScalarImageToHistogramGenerator.h Algorithms/itkMITKScalarImageToHistogramGenerator.txx Algorithms/itkTotalVariationDenoisingImageFilter.h Algorithms/itkTotalVariationDenoisingImageFilter.txx Algorithms/itkTotalVariationSingleIterationImageFilter.h Algorithms/itkTotalVariationSingleIterationImageFilter.txx Algorithms/mitkBilateralFilter.h Algorithms/mitkBilateralFilter.cpp Algorithms/mitkInstantiateAccessFunctions.h Algorithms/mitkPixelTypeList.h Algorithms/mitkPPArithmeticDec.h Algorithms/mitkPPArgCount.h Algorithms/mitkPPCat.h Algorithms/mitkPPConfig.h Algorithms/mitkPPControlExprIIf.h Algorithms/mitkPPControlIf.h Algorithms/mitkPPControlIIf.h Algorithms/mitkPPDebugError.h Algorithms/mitkPPDetailAutoRec.h Algorithms/mitkPPDetailDMCAutoRec.h Algorithms/mitkPPExpand.h Algorithms/mitkPPFacilitiesEmpty.h Algorithms/mitkPPFacilitiesExpand.h Algorithms/mitkPPLogicalBool.h Algorithms/mitkPPRepetitionDetailDMCFor.h Algorithms/mitkPPRepetitionDetailEDGFor.h Algorithms/mitkPPRepetitionDetailFor.h Algorithms/mitkPPRepetitionDetailMSVCFor.h Algorithms/mitkPPRepetitionFor.h Algorithms/mitkPPSeqElem.h Algorithms/mitkPPSeqForEach.h Algorithms/mitkPPSeqForEachProduct.h Algorithms/mitkPPSeq.h Algorithms/mitkPPSeqEnum.h Algorithms/mitkPPSeqSize.h Algorithms/mitkPPSeqToTuple.h Algorithms/mitkPPStringize.h Algorithms/mitkPPTupleEat.h Algorithms/mitkPPTupleElem.h Algorithms/mitkPPTupleRem.h Algorithms/mitkClippedSurfaceBoundsCalculator.h Algorithms/mitkExtractSliceFilter.h Algorithms/mitkConvert2Dto3DImageFilter.h Algorithms/mitkPlaneClipping.h Common/mitkExceptionMacro.h Common/mitkServiceBaseObject.h Common/mitkTestingMacros.h Common/mitkTesting.h DataManagement/mitkProportionalTimeGeometry.h DataManagement/mitkTimeGeometry.h DataManagement/mitkImageAccessByItk.h DataManagement/mitkImageCast.h DataManagement/mitkImagePixelAccessor.h DataManagement/mitkImagePixelReadAccessor.h DataManagement/mitkImagePixelWriteAccessor.h DataManagement/mitkImageReadAccessor.h DataManagement/mitkImageWriteAccessor.h DataManagement/mitkITKImageImport.h DataManagement/mitkITKImageImport.txx DataManagement/mitkImageToItk.h DataManagement/mitkImageToItk.txx DataManagement/mitkTimeSlicedGeometry.h # Deprecated, empty for compatibilty reasons. Interactions/mitkEventMapperAddOn.h Interfaces/mitkIDataNodeReader.h Rendering/mitkLocalStorageHandler.h IO/mitkPixelTypeTraits.h ) set(CPP_FILES Algorithms/mitkBaseDataSource.cpp - Algorithms/mitkCompareImageFilter.cpp + Algorithms/mitkCompareImageDataFilter.cpp + Algorithms/mitkMultiChannelImageDataComparisonFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkCoreActivator.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataStorage.cpp # DataManagement/mitkDataTree.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataNodeFactory.cpp # DataManagement/mitkDataTreeStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkGeometry2D.cpp DataManagement/mitkGeometry2DData.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkLandmarkBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkVector.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkShaderProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkMaterial.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilters.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEvent.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkState.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkTransition.cpp Interactions/mitkWheelEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkCrosshairPositionEvent.cpp Interfaces/mitkInteractionEventObserver.cpp Interfaces/mitkIShaderRepository.cpp Interfaces/mitkIPropertyAliases.cpp Interfaces/mitkIPropertyDescriptions.cpp Interfaces/mitkIPropertyExtensions.cpp Interfaces/mitkIPropertyFilters.cpp IO/mitkBaseDataIOFactory.cpp IO/mitkCoreDataNodeReader.cpp IO/mitkDicomSeriesReader.cpp IO/mitkFileReader.cpp IO/mitkFileSeriesReader.cpp IO/mitkFileWriter.cpp # IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkImageWriter.cpp IO/mitkImageWriterFactory.cpp IO/mitkItkImageFileIOFactory.cpp IO/mitkItkImageFileReader.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkItkPictureWrite.cpp IO/mitkIOUtil.cpp IO/mitkLookupTableProperty.cpp IO/mitkOperation.cpp # IO/mitkPicFileIOFactory.cpp # IO/mitkPicFileReader.cpp # IO/mitkPicFileWriter.cpp # IO/mitkPicHelper.cpp # IO/mitkPicVolumeTimeSeriesIOFactory.cpp # IO/mitkPicVolumeTimeSeriesReader.cpp IO/mitkPixelType.cpp IO/mitkPointSetIOFactory.cpp IO/mitkPointSetReader.cpp IO/mitkPointSetWriter.cpp IO/mitkPointSetWriterFactory.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSTLFileIOFactory.cpp IO/mitkSTLFileReader.cpp IO/mitkSurfaceVtkWriter.cpp IO/mitkSurfaceVtkWriterFactory.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkVtiFileIOFactory.cpp IO/mitkVtiFileReader.cpp IO/mitkVtkImageIOFactory.cpp IO/mitkVtkImageReader.cpp IO/mitkVtkSurfaceIOFactory.cpp IO/mitkVtkSurfaceReader.cpp IO/vtkPointSetXMLParser.cpp IO/mitkLog.cpp Rendering/mitkBaseRenderer.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkGeometry2DDataMapper2D.cpp Rendering/mitkGeometry2DDataVtkMapper3D.cpp Rendering/mitkGLMapper.cpp Rendering/mitkGradientBackground.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp Rendering/mitkPointSetGLMapper2D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkPolyDataGLMapper2D.cpp Rendering/mitkSurfaceGLMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVolumeDataVtkMapper3D.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkShaderRepository.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp Rendering/mitkRenderingTestHelper.cpp Rendering/mitkOverlay.cpp Rendering/mitkVtkOverlay.cpp Rendering/mitkVtkOverlay2D.cpp Rendering/mitkVtkOverlay3D.cpp Rendering/mitkOverlayManager.cpp Rendering/mitkAbstractOverlayLayouter.cpp Rendering/mitkTextOverlay2D.cpp Rendering/mitkTextOverlay3D.cpp Rendering/mitkLabelOverlay3D.cpp Rendering/mitkOverlay2DLayouter.cpp Common/mitkException.cpp Common/mitkCommon.h Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp Common/mitkCoreServices.cpp ) list(APPEND CPP_FILES ${CppMicroServices_SOURCES}) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml Shaders/mitkShaderLighting.xml mitkLevelWindowPresets.xml ) diff --git a/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp b/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp index c5ce82926b..744df3b682 100644 --- a/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp +++ b/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp @@ -1,305 +1,305 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // mitk includes #include "mitkImageToOpenCVImageFilter.h" #include "mitkOpenCVToMitkImageFilter.h" #include #include #include #include #include "mitkItkImageFileReader.h" #include "mitkImageReadAccessor.h" #include "mitkImageSliceSelector.h" // itk includes #include #include #include // define test pixel indexes and intensities and other values typedef itk::RGBPixel< unsigned char > TestUCRGBPixelType; cv::Size testImageSize; cv::Point pos1; cv::Point pos2; cv::Point pos3; cv::Vec3b color1; cv::Vec3b color2; cv::Vec3b color3; uchar greyValue1; uchar greyValue2; uchar greyValue3; /*! Documentation * Test for image conversion of OpenCV images and mitk::Images. It tests the classes * OpenCVToMitkImageFilter and ImageToOpenCVImageFilter */ // Some declarations template void ComparePixels( itk::Image,VImageDimension>* image ); - void ReadImageDataAndConvertForthAndBack(std::string imageFileName); - void ConvertIplImageForthAndBack(mitk::Image::Pointer inputForCVMat, std::string imageFileName); void ConvertCVMatForthAndBack(mitk::Image::Pointer inputForCVMat, std::string imageFileName); + // Begin the test for mitkImage to OpenCV image conversion and back. int mitkOpenCVMitkConversionTest(int argc, char* argv[]) { MITK_TEST_BEGIN("ImageToOpenCVImageFilter") - // the first part of this test checks the conversion of a cv::Mat style OpenCV image. + //// the first part of this test checks the conversion of a cv::Mat style OpenCV image. - // we build an cv::Mat image - MITK_INFO << "setting test values"; - testImageSize = cv::Size(11,11); + //// we build an cv::Mat image + //MITK_INFO << "setting test values"; + //testImageSize = cv::Size(11,11); - pos1 = cv::Point(0,0); - pos2 = cv::Point(5,5); - pos3 = cv::Point(10,10); + //pos1 = cv::Point(0,0); + //pos2 = cv::Point(5,5); + //pos3 = cv::Point(10,10); - color1 = cv::Vec3b(50,0,0); - color2 = cv::Vec3b(0,128,0); - color3 = cv::Vec3b(0,0,255); + //color1 = cv::Vec3b(50,0,0); + //color2 = cv::Vec3b(0,128,0); + //color3 = cv::Vec3b(0,0,255); - greyValue1 = 0; - greyValue2 = 128; - greyValue3 = 255; + //greyValue1 = 0; + //greyValue2 = 128; + //greyValue3 = 255; - MITK_INFO << "generating test OpenCV image (RGB)"; - cv::Mat testRGBImage = cv::Mat::zeros( testImageSize, CV_8UC3 ); + //MITK_INFO << "generating test OpenCV image (RGB)"; + //cv::Mat testRGBImage = cv::Mat::zeros( testImageSize, CV_8UC3 ); - // generate some test intensity values - testRGBImage.at(pos1)= color1; - testRGBImage.at(pos2)= color2; - testRGBImage.at(pos3)= color3; + //// generate some test intensity values + //testRGBImage.at(pos1)= color1; + //testRGBImage.at(pos2)= color2; + //testRGBImage.at(pos3)= color3; - //cv::namedWindow("debug", CV_WINDOW_FREERATIO ); - //cv::imshow("debug", testRGBImage.clone()); - //cv::waitKey(0); + ////cv::namedWindow("debug", CV_WINDOW_FREERATIO ); + ////cv::imshow("debug", testRGBImage.clone()); + ////cv::waitKey(0); - // convert it to a mitk::Image - MITK_INFO << "converting OpenCV test image to mitk image and comparing scalar rgb values"; - mitk::OpenCVToMitkImageFilter::Pointer openCvToMitkFilter = - mitk::OpenCVToMitkImageFilter::New(); - openCvToMitkFilter->SetOpenCVMat( testRGBImage ); - openCvToMitkFilter->Update(); + //// convert it to a mitk::Image + //MITK_INFO << "converting OpenCV test image to mitk image and comparing scalar rgb values"; + //mitk::OpenCVToMitkImageFilter::Pointer openCvToMitkFilter = + // mitk::OpenCVToMitkImageFilter::New(); + //openCvToMitkFilter->SetOpenCVMat( testRGBImage ); + //openCvToMitkFilter->Update(); - mitk::Image::Pointer mitkImage = openCvToMitkFilter->GetOutput(); - AccessFixedTypeByItk(mitkImage.GetPointer(), ComparePixels, - (itk::RGBPixel), // rgb image - (2) ); + //mitk::Image::Pointer mitkImage = openCvToMitkFilter->GetOutput(); + //AccessFixedTypeByItk(mitkImage.GetPointer(), ComparePixels, + // (itk::RGBPixel), // rgb image + // (2) ); - // convert it back to OpenCV image - MITK_INFO << "converting mitk image to OpenCV image and comparing scalar rgb values"; - mitk::ImageToOpenCVImageFilter::Pointer mitkToOpenCv = mitk::ImageToOpenCVImageFilter::New(); - mitkToOpenCv->SetImage( mitkImage ); - cv::Mat openCvImage = mitkToOpenCv->GetOpenCVMat(); + //// convert it back to OpenCV image + //MITK_INFO << "converting mitk image to OpenCV image and comparing scalar rgb values"; + //mitk::ImageToOpenCVImageFilter::Pointer mitkToOpenCv = mitk::ImageToOpenCVImageFilter::New(); + //mitkToOpenCv->SetImage( mitkImage ); + //cv::Mat openCvImage = mitkToOpenCv->GetOpenCVMat(); - // and test equality of the sentinel pixel - cv::Vec3b convertedColor1 = openCvImage.at(pos1); - cv::Vec3b convertedColor2 = openCvImage.at(pos2); - cv::Vec3b convertedColor3 = openCvImage.at(pos3); + //// and test equality of the sentinel pixel + //cv::Vec3b convertedColor1 = openCvImage.at(pos1); + //cv::Vec3b convertedColor2 = openCvImage.at(pos2); + //cv::Vec3b convertedColor3 = openCvImage.at(pos3); - MITK_TEST_CONDITION( color1 == convertedColor1, "Testing if initially created color values " << static_cast( color1[0] ) << ", " << static_cast( color1[1] ) << ", " << static_cast( color1[2] ) << " matches the color values " << static_cast( convertedColor1[0] ) << ", " << static_cast( convertedColor1[1] ) << ", " << static_cast( convertedColor1[2] ) << " at the same position " << pos1.x << ", " << pos1.y << " in the back converted OpenCV image" ) + //MITK_TEST_CONDITION( color1 == convertedColor1, "Testing if initially created color values " << static_cast( color1[0] ) << ", " << static_cast( color1[1] ) << ", " << static_cast( color1[2] ) << " matches the color values " << static_cast( convertedColor1[0] ) << ", " << static_cast( convertedColor1[1] ) << ", " << static_cast( convertedColor1[2] ) << " at the same position " << pos1.x << ", " << pos1.y << " in the back converted OpenCV image" ) - MITK_TEST_CONDITION( color2 == convertedColor2, "Testing if initially created color values " << static_cast( color2[0] ) << ", " << static_cast( color2[1] ) << ", " << static_cast( color2[2] ) << " matches the color values " << static_cast( convertedColor2[0] ) << ", " << static_cast( convertedColor2[1] ) << ", " << static_cast( convertedColor2[2] ) << " at the same position " << pos2.x << ", " << pos2.y << " in the back converted OpenCV image" ) + //MITK_TEST_CONDITION( color2 == convertedColor2, "Testing if initially created color values " << static_cast( color2[0] ) << ", " << static_cast( color2[1] ) << ", " << static_cast( color2[2] ) << " matches the color values " << static_cast( convertedColor2[0] ) << ", " << static_cast( convertedColor2[1] ) << ", " << static_cast( convertedColor2[2] ) << " at the same position " << pos2.x << ", " << pos2.y << " in the back converted OpenCV image" ) - MITK_TEST_CONDITION( color3 == convertedColor3, "Testing if initially created color values " << static_cast( color3[0] ) << ", " << static_cast( color3[1] ) << ", " << static_cast( color3[2] ) << " matches the color values " << static_cast( convertedColor3[0] ) << ", " << static_cast( convertedColor3[1] ) << ", " << static_cast( convertedColor3[2] ) << " at the same position " << pos3.x << ", " << pos3.y << " in the back converted OpenCV image" ) + //MITK_TEST_CONDITION( color3 == convertedColor3, "Testing if initially created color values " << static_cast( color3[0] ) << ", " << static_cast( color3[1] ) << ", " << static_cast( color3[2] ) << " matches the color values " << static_cast( convertedColor3[0] ) << ", " << static_cast( convertedColor3[1] ) << ", " << static_cast( convertedColor3[2] ) << " at the same position " << pos3.x << ", " << pos3.y << " in the back converted OpenCV image" ) // the second part of this test checks the conversion of mitk::Images to Ipl images and cv::Mat and back. for(unsigned int i = 1; i < argc; ++i ) { ReadImageDataAndConvertForthAndBack(argv[i]); } MITK_TEST_END(); } template void ComparePixels( itk::Image,VImageDimension>* image ) { typedef itk::RGBPixel PixelType; typedef itk::Image ImageType; typename ImageType::IndexType pixelIndex; pixelIndex[0] = pos1.x; pixelIndex[1] = pos1.y; PixelType onePixel = image->GetPixel( pixelIndex ); MITK_TEST_CONDITION( color1[0] == onePixel.GetBlue(), "Testing if blue value (= " << static_cast(color1[0]) << ") at postion " << pos1.x << ", " << pos1.y << " in OpenCV image is " << "equals the blue value (= " << static_cast(onePixel.GetBlue()) << ")" << " in the generated mitk image"); pixelIndex[0] = pos2.x; pixelIndex[1] = pos2.y; onePixel = image->GetPixel( pixelIndex ); MITK_TEST_CONDITION( color2[1] == onePixel.GetGreen(), "Testing if green value (= " << static_cast(color2[1]) << ") at postion " << pos2.x << ", " << pos2.y << " in OpenCV image is " << "equals the green value (= " << static_cast(onePixel.GetGreen()) << ")" << " in the generated mitk image"); pixelIndex[0] = pos3.x; pixelIndex[1] = pos3.y; onePixel = image->GetPixel( pixelIndex ); MITK_TEST_CONDITION( color3[2] == onePixel.GetRed(), "Testing if red value (= " << static_cast(color3[2]) << ") at postion " << pos3.x << ", " << pos3.y << " in OpenCV image is " << "equals the red value (= " << static_cast(onePixel.GetRed()) << ")" << " in the generated mitk image"); } void ReadImageDataAndConvertForthAndBack(std::string imageFileName) { // first we load an mitk::Image from the data repository mitk::ItkImageFileReader::Pointer reader = mitk::ItkImageFileReader::New(); reader->SetFileName(imageFileName); reader->Update(); mitk::Image::Pointer mitkTestImage = reader->GetOutput(); // some format checking mitk::Image::Pointer resultImg = NULL; if( mitkTestImage->GetDimension() <= 3 ) { if( mitkTestImage->GetDimension() > 2 && mitkTestImage->GetDimension(2) == 1 ) { mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New(); sliceSelector->SetInput(mitkTestImage); sliceSelector->SetSliceNr(0); sliceSelector->Update(); resultImg = sliceSelector->GetOutput()->Clone(); } else if(mitkTestImage->GetDimension() < 3) { resultImg = mitkTestImage; } else { return; // 3D images are not supported, except with just one slice. } } else { return; // 4D images are not supported! } - ConvertIplImageForthAndBack(resultImg, imageFileName); + //ConvertIplImageForthAndBack(resultImg, imageFileName); ConvertCVMatForthAndBack(resultImg, imageFileName); } void ConvertCVMatForthAndBack(mitk::Image::Pointer inputForCVMat, std::string imageFileName) { // now we convert it to OpenCV IplImage mitk::ImageToOpenCVImageFilter::Pointer toOCvConverter = mitk::ImageToOpenCVImageFilter::New(); toOCvConverter->SetImage(inputForCVMat); cv::Mat cvmatTestImage = toOCvConverter->GetOpenCVMat(); - MITK_TEST_CONDITION_REQUIRED( &cvmatTestImage != NULL, "Conversion to cv::Mat successful!"); + MITK_TEST_CONDITION_REQUIRED( !cvmatTestImage.empty(), "Conversion to cv::Mat successful!"); - //// temp visualization of IplImage + // temp visualization of IplImage //cv::Mat matData = cv::Mat(iplTestImage, true); - //double minVal, maxVal; - //cv::minMaxLoc(matData, &minVal, &maxVal); - //cv::Mat uCCvImage; - //matData.convertTo(uCCvImage,CV_8U, 255.0/(maxVal - minVal), -minVal ); - //cv::namedWindow("IplImage", CV_WINDOW_AUTOSIZE); - //cv::imshow("IplImage", uCCvImage); - //cv::waitKey(10000); - //cv::destroyWindow("IplImage"); - //// end temp visualization of IplImage + double minVal, maxVal; + cv::minMaxLoc(cvmatTestImage, &minVal, &maxVal); + cv::Mat uCCvImage; + cvmatTestImage.convertTo(uCCvImage,CV_8U, 255.0/(maxVal - minVal), -minVal ); + cv::namedWindow("IplImage", CV_WINDOW_AUTOSIZE); + cv::imshow("IplImage", uCCvImage); + cv::waitKey(10000); + cv::destroyWindow("IplImage"); + // end temp visualization of IplImage mitk::OpenCVToMitkImageFilter::Pointer toMitkConverter = mitk::OpenCVToMitkImageFilter::New(); toMitkConverter->SetOpenCVMat(cvmatTestImage); toMitkConverter->Update(); // initialize the image with the input image, since we want to test equality and OpenCV does not feature geometries and spacing mitk::Image::Pointer result = inputForCVMat->Clone(); mitk::ImageReadAccessor resultAcc(toMitkConverter->GetOutput(), toMitkConverter->GetOutput()->GetSliceData()); result->SetImportSlice(const_cast(resultAcc.GetData())); - //// temp visualization of IplImage - //mitk::ImageToOpenCVImageFilter::Pointer openCvImageCon = mitk::ImageToOpenCVImageFilter::New(); - //openCvImageCon->SetImage(result); - //cv::Mat cvImage2 = cv::Mat(openCvImageCon->GetOpenCVImage(), true); + // temp visualization of IplImage + mitk::ImageToOpenCVImageFilter::Pointer openCvImageCon = mitk::ImageToOpenCVImageFilter::New(); + openCvImageCon->SetImage(result); + cv::Mat cvImage2 = cv::Mat(openCvImageCon->GetOpenCVImage(), true); //double minVal, maxVal; - //cv::minMaxLoc(cvImage2, &minVal, &maxVal); + cv::minMaxLoc(cvImage2, &minVal, &maxVal); //cv::Mat uCCvImage; - //cvImage2.convertTo(uCCvImage,CV_8U, 255.0/(maxVal - minVal), -minVal ); - //cv::namedWindow("IplImage", CV_WINDOW_AUTOSIZE); - //cv::imshow("IplImage", uCCvImage); - //cv::waitKey(10000); - //cv::destroyWindow("IplImage"); - //// end temp visualization of IplImage + cvImage2.convertTo(uCCvImage,CV_8U, 255.0/(maxVal - minVal), -minVal ); + cv::namedWindow("IplImage", CV_WINDOW_AUTOSIZE); + cv::imshow("IplImage", uCCvImage); + cv::waitKey(10000); + cv::destroyWindow("IplImage"); + // end temp visualization of IplImage if( result->GetPixelType().GetNumberOfComponents() == 1 ) { MITK_TEST_EQUAL( result, inputForCVMat, "Testing equality of input and output image of cv::Mat conversion for " << imageFileName ); } else if( result->GetPixelType().GetNumberOfComponents() == 3 ) { - MITK_WARN << "Implement MITK_TEST_EQUAL functionality for three component images!"; + MITK_TEST_EQUAL( result, inputForCVMat, "Testing equality of input and output image of cv::Mat conversion for " << imageFileName ); + //MITK_WARN << "Implement MITK_TEST_EQUAL functionality for three component images!"; } else { MITK_WARN << "Unhandled number of components used to test equality, please enhance test!"; } } void ConvertIplImageForthAndBack(mitk::Image::Pointer inputForIpl, std::string imageFileName) { // now we convert it to OpenCV IplImage mitk::ImageToOpenCVImageFilter::Pointer toOCvConverter = mitk::ImageToOpenCVImageFilter::New(); toOCvConverter->SetImage(inputForIpl); IplImage* iplTestImage = toOCvConverter->GetOpenCVImage(); MITK_TEST_CONDITION_REQUIRED( iplTestImage != NULL, "Conversion to OpenCv IplImage successful!"); mitk::OpenCVToMitkImageFilter::Pointer toMitkConverter = mitk::OpenCVToMitkImageFilter::New(); toMitkConverter->SetOpenCVImage(iplTestImage); toMitkConverter->Update(); // initialize the image with the input image, since we want to test equality and OpenCV does not feature geometries and spacing mitk::Image::Pointer result = inputForIpl->Clone(); mitk::ImageReadAccessor resultAcc(toMitkConverter->GetOutput(), toMitkConverter->GetOutput()->GetSliceData()); result->SetImportSlice(const_cast(resultAcc.GetData())); if( result->GetPixelType().GetNumberOfComponents() == 1 ) { MITK_TEST_EQUAL( result, inputForIpl, "Testing equality of input and output image of IplImage conversion for " << imageFileName ); } else if( result->GetPixelType().GetNumberOfComponents() == 3 ) { MITK_WARN << "Implement MITK_TEST_EQUAL functionality for three component images!"; } else { MITK_WARN << "Unhandled number of components used to test equality, please enhance test!"; } } \ No newline at end of file