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