diff --git a/Modules/Core/ImageBase/include/otbImage.h b/Modules/Core/ImageBase/include/otbImage.h index ba484e90bac0b8d8ea3a0d66843e796eee455fcd..d3943b35190b8080e374cfe1dfa684350bb8d385 100644 --- a/Modules/Core/ImageBase/include/otbImage.h +++ b/Modules/Core/ImageBase/include/otbImage.h @@ -32,6 +32,49 @@ #include "otbImageMetadataInterfaceBase.h" +namespace otb +{ +namespace internal +{ + template < class ImageType > + typename ImageType::SpacingType GetSignedSpacing( ImageType * input) + { + typename ImageType::SpacingType spacing = input->GetSpacing(); + typename ImageType::DirectionType direction = input->GetDirection(); + for ( unsigned int i = 0 ; i < ImageType::ImageDimension ; i++ ) + { + spacing[i] *= direction[i][i] ; + } + return spacing; + } + + template < class InputImage , typename SpacingType > + void SetSignedSpacing( InputImage input , SpacingType spacing ) + { + // TODO check for spacing size ==> error + typename InputImage::DirectionType direction = input->GetDirection(); + for ( unsigned int i = 0 ; i < InputImage::VImageDimension ; i++ ) + { + // TODO check if spacing[i] = 0 ==> error + if ( spacing[ i ] < 0 ) + { + if ( direction[i][i] > 0 ) + { + for ( unsigned int j = 0 ; j < InputImage::VImageDimension ; j++ ) + { + direction[j][i] = - direction[j][i]; + } + } + spacing[i] = -spacing[i]; + } + } + input->SetDirection( direction ); + input->SetSpacing( spacing ); + } +} +} + + namespace otb { /** \class Image diff --git a/Modules/Core/ImageBase/include/otbImage.txx b/Modules/Core/ImageBase/include/otbImage.txx index 9173f8384ffc24255376b72b41fced95ed4f5c4f..e02892ef55687193aaf53d4f75c2eab8ac4ff59c 100644 --- a/Modules/Core/ImageBase/include/otbImage.txx +++ b/Modules/Core/ImageBase/include/otbImage.txx @@ -170,11 +170,14 @@ void Image<TPixel, VImageDimension> { if ( spacing[i] < 0.0 ) { + if ( this->m_Direction[i][i] > 0 ) + { for ( unsigned j = 0; j < VImageDimension; ++j ) { this->m_Direction[j][i] = - this->m_Direction[j][i]; - } - spacing[i] = - spacing[i]; + } + } + spacing[i] = - spacing[i]; } } this->SetSpacing(spacing); @@ -188,9 +191,12 @@ void Image<TPixel, VImageDimension> { if ( spacing[i] < 0.0 ) { - for ( unsigned j = 0; j < VImageDimension; ++j ) + if ( this->m_Direction[i][i] > 0 ) { - this->m_Direction[j][i] = - this->m_Direction[j][i]; + for ( unsigned j = 0; j < VImageDimension; ++j ) + { + this->m_Direction[j][i] = - this->m_Direction[j][i]; + } } spacing[i] = - spacing[i]; } @@ -206,9 +212,12 @@ void Image<TPixel, VImageDimension> { if ( spacing[i] < 0.0 ) { - for ( unsigned j = 0; j < ImageDimension; ++j ) + if ( this->m_Direction[i][i] > 0 ) { - this->m_Direction[j][i] = - this->m_Direction[j][i]; + for ( unsigned j = 0; j < VImageDimension; ++j ) + { + this->m_Direction[j][i] = - this->m_Direction[j][i]; + } } spacing[i] = - spacing[i]; } diff --git a/Modules/Core/ImageBase/include/otbVectorImage.txx b/Modules/Core/ImageBase/include/otbVectorImage.txx index adb6bf42cc0332d4d8f5e6f0666109ad5003a344..e69a9fd14d44cfe0ef080178a9d8dc0705bcc9c7 100644 --- a/Modules/Core/ImageBase/include/otbVectorImage.txx +++ b/Modules/Core/ImageBase/include/otbVectorImage.txx @@ -172,11 +172,14 @@ void VectorImage<TPixel, VImageDimension> { if ( spacing[i] < 0.0 ) { + if ( this->m_Direction[i][i] > 0 ) + { for ( unsigned j = 0; j < VImageDimension; ++j ) { this->m_Direction[j][i] = - this->m_Direction[j][i]; - } - spacing[i] = - spacing[i]; + } + } + spacing[i] = - spacing[i]; } } this->SetSpacing(spacing); @@ -190,9 +193,12 @@ void VectorImage<TPixel, VImageDimension> { if ( spacing[i] < 0.0 ) { - for ( unsigned j = 0; j < VImageDimension; ++j ) + if ( this->m_Direction[i][i] > 0 ) { - this->m_Direction[j][i] = - this->m_Direction[j][i]; + for ( unsigned j = 0; j < VImageDimension; ++j ) + { + this->m_Direction[j][i] = - this->m_Direction[j][i]; + } } spacing[i] = - spacing[i]; } @@ -208,9 +214,12 @@ void VectorImage<TPixel, VImageDimension> { if ( spacing[i] < 0.0 ) { - for ( unsigned j = 0; j < VImageDimension; ++j ) + if ( this->m_Direction[i][i] > 0 ) { - this->m_Direction[j][i] = - this->m_Direction[j][i]; + for ( unsigned j = 0; j < VImageDimension; ++j ) + { + this->m_Direction[j][i] = - this->m_Direction[j][i]; + } } spacing[i] = - spacing[i]; } diff --git a/Modules/Feature/Density/include/otbPointSetToDensityImageFilter.txx b/Modules/Feature/Density/include/otbPointSetToDensityImageFilter.txx index 603c52e583894a897a3220052fe801c9c3224ec7..09c672b71555e2a5c95f5f786dc24f38e3789afd 100644 --- a/Modules/Feature/Density/include/otbPointSetToDensityImageFilter.txx +++ b/Modules/Feature/Density/include/otbPointSetToDensityImageFilter.txx @@ -113,7 +113,7 @@ PointSetToDensityImageFilter<TInputPointSet, TOutputImage, TDensityFunction> region.SetIndex(start); outputPtr->SetOrigin(this->GetOrigin()); - outputPtr->SetSignedSpacing(this->GetSignedSpacing()); + outputPtr->SetSignedSpacing(this->GetSpacing()); outputPtr->SetRegions(region); } diff --git a/Modules/Filtering/ImageManipulation/include/otbGridResampleImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbGridResampleImageFilter.txx index 6b8411967a0fc1cbf3d49343fa4a59126713efad..dced764cd856e4ef25f864712c22208237a362f0 100644 --- a/Modules/Filtering/ImageManipulation/include/otbGridResampleImageFilter.txx +++ b/Modules/Filtering/ImageManipulation/include/otbGridResampleImageFilter.txx @@ -24,6 +24,7 @@ #include "otbGridResampleImageFilter.h" #include "otbStreamingTraits.h" +#include "otbImage.h" #include "itkNumericTraits.h" #include "itkProgressReporter.h" @@ -68,7 +69,7 @@ GridResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecision> ::SetOutputParametersFromImage(const ImageBaseType * image) { this->SetOutputOrigin ( image->GetOrigin() ); - this->SetOutputSpacing ( image->GetSignedSpacing() ); + this->SetOutputSpacing ( internal::GetSignedSpacing( image ) ); this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() ); this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() ); } diff --git a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx index 73fb3f35c6bb2f064b016b9cea19b6ae6b3687f5..eaa41f3a221591b4079637a6688020cd4338a182 100644 --- a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx +++ b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx @@ -23,6 +23,7 @@ #include "otbStreamingResampleImageFilter.h" #include "itkProgressAccumulator.h" +#include "otbImage.h" namespace otb { @@ -121,7 +122,7 @@ StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionTy ::SetOutputParametersFromImage(const ImageBaseType * image) { this->SetOutputOrigin ( image->GetOrigin() ); - this->SetOutputSpacing ( image->GetSignedSpacing() ); + this->SetOutputSpacing ( internal::GetSignedSpacing( image ) ); this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() ); this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() ); } diff --git a/Modules/IO/ImageIO/include/otbImageFileReader.txx b/Modules/IO/ImageIO/include/otbImageFileReader.txx index 7c47d9f41a9197fa4b7b7e7cb1ff600ccf0aed3c..98a37bf87b51b5caade4258ab231a45b1f39c87a 100644 --- a/Modules/IO/ImageIO/include/otbImageFileReader.txx +++ b/Modules/IO/ImageIO/include/otbImageFileReader.txx @@ -324,13 +324,18 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> double origin[TOutputImage::ImageDimension]; typename TOutputImage::DirectionType direction; std::vector<double> axis; + int spacing_sign (0); for (unsigned int i = 0; i < TOutputImage::ImageDimension; ++i) { if (i < this->m_ImageIO->GetNumberOfDimensions()) { dimSize[i] = this->m_ImageIO->GetDimensions(i); - spacing[i] = this->m_ImageIO->GetSpacing(i); + if ( this->m_ImageIO->GetSpacing(i) < 0 ) + spacing_sign = -1; + else + spacing_sign = 1; + spacing[i] = spacing_sign * this->m_ImageIO->GetSpacing(i); origin[i] = this->m_ImageIO->GetOrigin(i); // Please note: direction cosines are stored as columns of the // direction matrix @@ -339,7 +344,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> { if (j < this->m_ImageIO->GetNumberOfDimensions()) { - direction[j][i] = axis[j]; + direction[j][i] = spacing_sign * axis[j]; } else { @@ -387,9 +392,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> output->SetOrigin(origin); // Set the image origin output->SetDirection(direction); // Set the image direction cosines - output->SetSignedSpacing(spacing); // Set the image spacing - // Need to set spacing after direction as we are setting a signed spacing - // it might change signes of direction column + output->SetSpacing(spacing); // Set the image spacing if(!m_KeywordListUpToDate && !m_FilenameHelper->GetSkipGeom()) { diff --git a/Modules/IO/ImageIO/include/otbImageFileWriter.txx b/Modules/IO/ImageIO/include/otbImageFileWriter.txx index db1a85e821eb82271b6be22a2129963405a7dc0b..b1472291f1ae216f302757ad00b69bfd161b3630 100644 --- a/Modules/IO/ImageIO/include/otbImageFileWriter.txx +++ b/Modules/IO/ImageIO/include/otbImageFileWriter.txx @@ -554,15 +554,19 @@ ImageFileWriter<TInputImage> // Setup the ImageIO with information from inputPtr // m_ImageIO->SetNumberOfDimensions(TInputImage::ImageDimension); - const typename TInputImage::SpacingType& spacing = inputPtr->GetSignedSpacing(); + const typename TInputImage::SpacingType& spacing = inputPtr->GetSpacing(); const typename TInputImage::PointType& origin = inputPtr->GetOrigin(); const typename TInputImage::DirectionType& direction = inputPtr->GetDirection(); - + int direction_sign(0); for (unsigned int i = 0; i < TInputImage::ImageDimension; ++i) { + if ( direction[i][i] < 0 ) + direction_sign = -1; + else + direction_sign = 1; // Final image size m_ImageIO->SetDimensions(i, inputRegion.GetSize(i)); - m_ImageIO->SetSpacing(i, spacing[i]); + m_ImageIO->SetSpacing(i, direction_sign * spacing[i]); m_ImageIO->SetOrigin(i, origin[i] + static_cast<double>(inputRegion.GetIndex()[i]) * spacing[i]); vnl_vector<double> axisDirection(TInputImage::ImageDimension); @@ -570,7 +574,7 @@ ImageFileWriter<TInputImage> // direction matrix for (unsigned int j = 0; j < TInputImage::ImageDimension; ++j) { - axisDirection[j] = direction[j][i]; + axisDirection[j] = direction_sign * direction[j][i]; } m_ImageIO->SetDirection(i, axisDirection); } diff --git a/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx b/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx index 5fc2d4e6a4d9ce7bf576d4c5606d985963e5f6ba..ef069d7611504b432fc256d298afbb3a2bd489dd 100644 --- a/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx +++ b/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx @@ -27,6 +27,7 @@ #include "otbImageMetadataInterfaceFactory.h" #include "itkMetaDataObject.h" #include "otbMetaDataKey.h" +#include "otbImage.h" #include "gdal_alg.h" #include "stdint.h" //needed for uintptr_t @@ -126,7 +127,7 @@ OGRDataSourceToLabelImageFilter<TOutputImage> ::SetOutputParametersFromImage(const ImageBaseType * image) { this->SetOutputOrigin ( image->GetOrigin() ); - this->SetOutputSpacing ( image->GetSignedSpacing() ); + this->SetOutputSpacing ( internal::GetSignedSpacing( image ) ); this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() ); ImageMetadataInterfaceBase::Pointer imi = ImageMetadataInterfaceFactory::CreateIMI(image->GetMetaDataDictionary()); diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.txx b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.txx index 7197fcc99e102477a8746a9f586a92f456230711..837943fc6f9f4cc4350e737e86f4bf8c9a27bdf8 100644 --- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.txx +++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.txx @@ -127,7 +127,7 @@ VectorDataToLabelImageFilter<TVectorData, TOutputImage> ::SetOutputParametersFromImage(const ImageBaseType * src) { this->SetOutputOrigin ( src->GetOrigin() ); - this->SetOutputSpacing ( src->GetSignedSpacing() ); + this->SetOutputSpacing ( src->GetSpacing() ); this->SetOutputSize ( src->GetLargestPossibleRegion().GetSize() ); ImageMetadataInterfaceBase::Pointer imi = ImageMetadataInterfaceFactory::CreateIMI(src->GetMetaDataDictionary()); this->SetOutputProjectionRef(imi->GetProjectionRef()); @@ -301,10 +301,10 @@ VectorDataToLabelImageFilter<TVectorData, TOutputImage>::GenerateData() OutputIndexType bufferIndexOrigin = bufferedRegion.GetIndex(); OutputOriginType bufferOrigin; this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin); - geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSignedSpacing()[0]; - geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSignedSpacing()[1]; - geoTransform[1] = this->GetOutput()->GetSignedSpacing()[0]; - geoTransform[5] = this->GetOutput()->GetSignedSpacing()[1]; + geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSpacing()[0]; + geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSpacing()[1]; + geoTransform[1] = this->GetOutput()->GetSpacing()[0]; + geoTransform[5] = this->GetOutput()->GetSpacing()[1]; // FIXME: Here component 1 and 4 should be replaced by the orientation parameters geoTransform[2] = 0.; diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapFilter.txx b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapFilter.txx index c039272505f0d3ea922b4df24783c0c1aa0a1d5e..fa29f1bb9694ba87b7322267e1141b4a5bde26c2 100644 --- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapFilter.txx +++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapFilter.txx @@ -305,17 +305,17 @@ VectorDataToLabelMapFilter<TVectorData, TLabelMap> VertexType vertex; otbMsgDevMacro( "Polygon bounding region " << polygonExtRingBoundReg); otbMsgDevMacro( "output origin " << this->GetOutput()->GetOrigin()); - otbMsgDevMacro( "spacing " << this->GetOutput()->GetSignedSpacing()); + otbMsgDevMacro( "spacing " << this->GetOutput()->GetSpacing()); // For each position in the bounding region of the polygon for (double i = polygonExtRingBoundReg.GetOrigin(0); i < polygonExtRingBoundReg.GetOrigin(0) + polygonExtRingBoundReg.GetSize(0); - i += this->GetOutput()->GetSignedSpacing()[0]) + i += this->GetOutput()->GetSpacing()[0]) { vertex[0] = static_cast<VertexValueType>(i); for (double j = polygonExtRingBoundReg.GetOrigin(1); j < polygonExtRingBoundReg.GetOrigin(1) + polygonExtRingBoundReg.GetSize(1); - j += this->GetOutput()->GetSignedSpacing()[1]) + j += this->GetOutput()->GetSpacing()[1]) { vertex[1] = static_cast<VertexValueType>(j); diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapWithAttributesFilter.txx b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapWithAttributesFilter.txx index 20cced4295d38360cb85423aaa99104acd6a02a9..3a026a063a6cd1cd7487b75aeb0e4b5e9e31dbd7 100644 --- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapWithAttributesFilter.txx +++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapWithAttributesFilter.txx @@ -148,7 +148,7 @@ void VectorDataToLabelMapWithAttributesFilter<TVectorData, TLabelMap> // Compute origin and size SizeType size; - SpacingType spacing = this->GetInput()->GetSignedSpacing(); + SpacingType spacing = this->GetInput()->GetSpacing(); OriginType origin = m_VectorDataProperties->GetBoundingRegion().GetOrigin(); for (unsigned int i=0; i<2; ++i) { diff --git a/Modules/Segmentation/Conversion/test/otbVectorDataToLabelMapFilter.cxx b/Modules/Segmentation/Conversion/test/otbVectorDataToLabelMapFilter.cxx index 787b09ab7bd852590c993c38b32af6b26d85ff91..94c7ab5bd12096bce1431b70adb49e0354c7d0d8 100644 --- a/Modules/Segmentation/Conversion/test/otbVectorDataToLabelMapFilter.cxx +++ b/Modules/Segmentation/Conversion/test/otbVectorDataToLabelMapFilter.cxx @@ -94,7 +94,7 @@ int otbVectorDataToLabelMapFilter(int argc, char * argv[]) //Set size, origin and spacing of the output labelmap myFilter->SetSize(p->GetBoundingRegion().GetImageRegion().GetSize()); myFilter->SetOrigin(origin); - myFilter->SetSpacing(reader->GetOutput()->GetSignedSpacing()); + myFilter->SetSpacing(reader->GetOutput()->GetSpacing()); // Translate the LabelMap in a labeld image LabelMapToLabelImageFilterType::Pointer labelMapToImageFilter = LabelMapToLabelImageFilterType::New(); diff --git a/Modules/ThirdParty/ITK/include/itkUnaryFunctorImageFilter.hxx b/Modules/ThirdParty/ITK/include/itkUnaryFunctorImageFilter.hxx index 0aa469df929022e758c5348a71b910747a22db13..e5872ddce4bd35ab2e00cbf98b97fac77dc7a22c 100644 --- a/Modules/ThirdParty/ITK/include/itkUnaryFunctorImageFilter.hxx +++ b/Modules/ThirdParty/ITK/include/itkUnaryFunctorImageFilter.hxx @@ -87,7 +87,7 @@ UnaryFunctorImageFilter< TInputImage, TOutputImage, TFunction > // dimensions to copy unsigned int i, j; const typename InputImageType::SpacingType & - inputSpacing = inputPtr->GetSignedSpacing(); + inputSpacing = inputPtr->GetSpacing(); const typename InputImageType::PointType & inputOrigin = inputPtr->GetOrigin(); const typename InputImageType::DirectionType & @@ -133,7 +133,7 @@ UnaryFunctorImageFilter< TInputImage, TOutputImage, TFunction > } // set the spacing and origin - outputPtr->SetSignedSpacing(outputSpacing); + outputPtr->SetSpacing( outputSpacing ); outputPtr->SetOrigin(outputOrigin); outputPtr->SetDirection(outputDirection); outputPtr->SetNumberOfComponentsPerPixel( // propagate vector length info