From 455b98bc227fec53ccb04d4bcdabfa566b1a5a27 Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@c-s.fr>
Date: Tue, 23 Oct 2007 11:59:33 +0000
Subject: [PATCH] Evolutions R&T

---
 ...bImageMultiSegmentationToRCC8GraphFilter.h |   1 +
 ...mageMultiSegmentationToRCC8GraphFilter.txx |  60 ++--
 .../otbImageToImageRCC8Calculator.txx         |  43 ++-
 .../otbPolygonToPolygonRCC8Calculator.h       | 130 +++++++
 .../otbPolygonToPolygonRCC8Calculator.txx     | 319 ++++++++++++++++++
 Code/SpatialReasoning/otbRCC8Graph.h          |  30 +-
 Code/SpatialReasoning/otbRCC8Graph.txx        |  46 +--
 .../SpatialReasoning/otbRCC8GraphFileReader.h |  30 +-
 .../otbRCC8GraphFileReader.txx                |  36 +-
 .../SpatialReasoning/otbRCC8GraphFileWriter.h |  17 -
 .../otbRCC8GraphFileWriter.txx                |  29 --
 Code/SpatialReasoning/otbRCC8VertexBase.h     |  26 +-
 Code/SpatialReasoning/otbRCC8VertexBase.txx   |  83 +++--
 .../otbRCC8VertexWithCompacity.h              |   8 +-
 .../otbRCC8VertexWithCompacity.txx            |  18 +-
 15 files changed, 640 insertions(+), 236 deletions(-)
 create mode 100644 Code/SpatialReasoning/otbPolygonToPolygonRCC8Calculator.h
 create mode 100644 Code/SpatialReasoning/otbPolygonToPolygonRCC8Calculator.txx

diff --git a/Code/SpatialReasoning/otbImageMultiSegmentationToRCC8GraphFilter.h b/Code/SpatialReasoning/otbImageMultiSegmentationToRCC8GraphFilter.h
index f49f5c58cb..8a95f91d6a 100644
--- a/Code/SpatialReasoning/otbImageMultiSegmentationToRCC8GraphFilter.h
+++ b/Code/SpatialReasoning/otbImageMultiSegmentationToRCC8GraphFilter.h
@@ -53,6 +53,7 @@ public:
   typedef typename OutputGraphType::Pointer OutputGraphPointerType;
   typedef typename OutputGraphType::VertexType VertexType;
   typedef typename VertexType::Pointer VertexPointerType;
+  typedef typename VertexType::PathType PathType;
   typedef typename OutputGraphType::VertexDescriptorType VertexDescriptorType;
   /** Knowledge enum typedef */
   typedef typename OutputGraphType::RCC8ValueType RCC8ValueType;
diff --git a/Code/SpatialReasoning/otbImageMultiSegmentationToRCC8GraphFilter.txx b/Code/SpatialReasoning/otbImageMultiSegmentationToRCC8GraphFilter.txx
index d7192271f2..f8e03ff525 100644
--- a/Code/SpatialReasoning/otbImageMultiSegmentationToRCC8GraphFilter.txx
+++ b/Code/SpatialReasoning/otbImageMultiSegmentationToRCC8GraphFilter.txx
@@ -20,11 +20,13 @@
 
 #include "otbImageMultiSegmentationToRCC8GraphFilter.h"
 #include "itkMinimumMaximumImageCalculator.h"
-#include "otbImageToImageRCC8Calculator.h"
+#include "otbPolygonToPolygonRCC8Calculator.h"
 #include "otbRCC8VertexIterator.h"
 #include "otbRCC8InEdgeIterator.h"
 #include "otbRCC8OutEdgeIterator.h"
 #include "itkProgressReporter.h"
+#include "otbImageToEdgePathFilter.h"
+#include "otbSimplifyPathListFilter.h"
 
 namespace otb
 {
@@ -135,13 +137,20 @@ ImageMultiSegmentationToRCC8GraphFilter<TInputImage, TOutputGraph>
   // Ouptut graph pointer 
   OutputGraphPointerType graph = this->GetOutput();
 
+
+
+
   // invert value vector
   RCC8ValueType invert[8]={OTB_RCC8_DC,OTB_RCC8_EC,OTB_RCC8_PO,OTB_RCC8_TPPI,
 			   OTB_RCC8_TPP,OTB_RCC8_NTPPI,OTB_RCC8_NTPP,OTB_RCC8_EQ};
 
   // Some typedefs
+  typedef otb::ImageToEdgePathFilter<InputImageType,PathType> EdgeExtractionFilterType;
+  typedef otb::SimplifyPathListFilter<PathType> SimplifyPathFilterType;
+  typedef typename SimplifyPathFilterType::PathListType PathListType;
+
   typedef itk::MinimumMaximumImageCalculator<InputImageType> MinMaxCalculatorType;
-  typedef ImageToImageRCC8Calculator<InputImageType> RCC8CalculatorType;
+  typedef PolygonToPolygonRCC8Calculator<PathType> RCC8CalculatorType;
   typedef RCC8VertexIterator<OutputGraphType> VertexIteratorType; 
   typedef RCC8InEdgeIterator<OutputGraphType> InEdgeIteratorType;
   typedef RCC8OutEdgeIterator<OutputGraphType> OutEdgeIteratorType;
@@ -164,18 +173,27 @@ ImageMultiSegmentationToRCC8GraphFilter<TInputImage, TOutputGraph>
       maxLabelVector.push_back(minMax->GetMaximum());
       otbMsgDebugMacro(<<"Number of objects in image "<<segmentationImageIndex<<": "
 	       <<minMax->GetMaximum());
-      
-      // Add the image to the segmentation image list of the output graph
-      graph->GetSegmentationImageList()->PushBack(it.Get());
 
       // then for each region of the images
       for(PixelType label=1; label<=maxLabelVector.back();++label)
 	{
+	  typename PathListType::Pointer region = PathListType::New();
+	  typename EdgeExtractionFilterType::Pointer extraction = EdgeExtractionFilterType::New();
+	  extraction->SetInput(it.Get());
+	  extraction->SetForegroundValue(label);
+	  extraction->Update();
+	  region->PushBack(extraction->GetOutput());
+	  typename SimplifyPathFilterType::Pointer simplifier = SimplifyPathFilterType::New();
+	  simplifier->SetInput(region);
+	  simplifier->SetTolerance(0.1);
+	  simplifier->Update();
+
 	  // Create a new vertex
-	  VertexPointerType vertex = VertexType::New();
+	  VertexPointerType vertex = VertexType::New(); 
 	  // Set its properties
-	  vertex->SetSegmentationImageIndex(segmentationImageIndex);
-	  vertex->SetObjectLabelInImage(label);
+	  vertex->SetPath(simplifier->GetOutput()->GetNthElement(0));
+	  vertex->SetSegmentationLevel(segmentationImageIndex/2);
+	  vertex->SetSegmentationType(segmentationImageIndex%2);
 	  // Put it in the graph
 	  graph->SetVertex(vertexIndex,vertex);
 	  vertexIndex++;
@@ -194,23 +212,14 @@ ImageMultiSegmentationToRCC8GraphFilter<TInputImage, TOutputGraph>
     {
       for(vIt2.GoToBegin();!vIt2.IsAtEnd();++vIt2)
 	{
-	  // Get the segmentation images indexes 
-	  unsigned int source = vIt1.Get()->GetSegmentationImageIndex();
-	  unsigned int target = vIt2.Get()->GetSegmentationImageIndex();
-	 
-	  // We do not examine each couple because of the RCC8 simetry
-	  if(source<target)
+	  //We do not examine each couple because of the RCC8 symmetry
+	  if(vIt1.GetIndex()<vIt2.GetIndex())
 	    {
-	      // Get the labels of source and target
-	      PixelType label1 = vIt1.Get()->GetObjectLabelInImage();	 
-	      PixelType label2 = vIt2.Get()->GetObjectLabelInImage();
-
+	      
 	      // Compute the RCC8 relation
 	      typename RCC8CalculatorType::Pointer calc = RCC8CalculatorType::New();
-	      calc->SetInput1(segList->GetNthElement(source));
-	      calc->SetInsideValue1(label1);
-	      calc->SetInput2(segList->GetNthElement(target));
-	      calc->SetInsideValue2(label2);
+	      calc->SetPolygon1(vIt1.Get()->GetPath());
+	      calc->SetPolygon2(vIt2.Get()->GetPath());
 	      RCC8ValueType value=OTB_RCC8_DC;
 	      
 	      // if the optimisations are activated
@@ -269,7 +278,7 @@ ImageMultiSegmentationToRCC8GraphFilter<TInputImage, TOutputGraph>
 		    {
 		      // Else trigger the computation
 		      // (which will take the optimisation phase info into account)
-		      calc->Update();
+		      calc->Compute();
 		      value=calc->GetValue();
 		    }
 		  // otbMsgDebugMacro(<<"RCC8GraphFilter: Leaving optimisation loop");
@@ -277,7 +286,7 @@ ImageMultiSegmentationToRCC8GraphFilter<TInputImage, TOutputGraph>
 	      // If the optimisations are not activated
 	      else
 		{
-		  calc->Update();
+		  calc->Compute();
 		  value=calc->GetValue();
 		}
 	      m_Accumulator[value]+=1;
@@ -289,12 +298,13 @@ ImageMultiSegmentationToRCC8GraphFilter<TInputImage, TOutputGraph>
 		  otbMsgDevMacro(<<"Adding edge: "<<vIt1.GetIndex()<<" -> "<<vIt2.GetIndex()<<": "<<value);
 		  graph->AddEdge(vIt1.GetIndex(),vIt2.GetIndex(),value);
 		}
-	    }
+	    }	    
 	  progress.CompletedPixel();
 	  progress.CompletedPixel();
 	}
     }
 }
+
 template <class TInputImage, class TOutputGraph>
 void
 ImageMultiSegmentationToRCC8GraphFilter<TInputImage, TOutputGraph>
diff --git a/Code/SpatialReasoning/otbImageToImageRCC8Calculator.txx b/Code/SpatialReasoning/otbImageToImageRCC8Calculator.txx
index 5ad5d84173..82430a6c2b 100644
--- a/Code/SpatialReasoning/otbImageToImageRCC8Calculator.txx
+++ b/Code/SpatialReasoning/otbImageToImageRCC8Calculator.txx
@@ -29,6 +29,9 @@
 #include "otbBinaryImageMinimalBoundingRegionCalculator.h"
 #include "otbMacro.h"
 
+//TODELETE  #include "otbImageFileWriter.h"
+//TODELETE  #include "itkCastImageFilter.h"
+
 namespace otb
 {     
   /**
@@ -132,19 +135,27 @@ namespace otb
     region2=rc->GetRegion();
     // otbMsgDebugMacro(<<"RCC8Calculator->ComputeMinimalRegion() Region1: index: "<<region1.GetIndex()<<" size: "<<region1.GetSize());
     // otbMsgDebugMacro(<<"RCC8Calculator->ComputeMinimalRegion() Region2: index: "<<region2.GetIndex()<<" size: "<<region2.GetSize());
+    
+  //TODELETE     std::cout<<"RCC8Calculator->ComputeMinimalRegion() Region1: index: "<<region1.GetIndex()<<" size: "<<region1.GetSize()<<std::endl;
+ //TODELETE      std::cout<<"RCC8Calculator->ComputeMinimalRegion() Region2: index: "<<region2.GetIndex()<<" size: "<<region2.GetSize()<<std::endl;
+
     typename ImageType::SizeType size;
     typename ImageType::IndexType index;
     
     for(int i=0;i<ImageType::ImageDimension;i++)
       {
-	index[i]=std::max(region1.GetIndex()[i],region2.GetIndex()[i]);
-	int potSize = std::min(region1.GetIndex()[i]+region1.GetSize()[i],
+	index[i]=std::min(region1.GetIndex()[i],region2.GetIndex()[i]);
+	int potSize = std::max(region1.GetIndex()[i]+region1.GetSize()[i],
 			 region2.GetIndex()[i]+region2.GetSize()[i]);
 	size[i]=(potSize-index[i]<0 ? 0 : potSize-index[i]);
       }
     region.SetIndex(index);
     region.SetSize(size);
+    region.PadByRadius(2);
+    region.Crop(image1->GetLargestPossibleRegion());
+    region.Crop(image2->GetLargestPossibleRegion());
     // otbMsgDebugMacro(<<"RCC8Calculator->ComputeMinimalRegion(): index: "<<index<<" size: "<<size);
+    //TODELETE   std::cout<<"RCC8Calculator->ComputeMinimalRegion(): index: "<<index<<" size: "<<size<<std::endl;
     return region;
   }
 /**
@@ -258,6 +269,7 @@ ImageToImageRCC8Calculator<TInputImage>
     typename InvertFilterType::Pointer invert = InvertFilterType::New();
     typename AndFilterType::Pointer andFilter = AndFilterType::New();
     /// The exterior is the inverted input image
+    invert->SetMaximum(true);
     invert->SetInput(m_BoolImage1);
     andFilter->SetInput1(m_BoolImage2);
     andFilter->SetInput2(invert->GetOutput());
@@ -275,17 +287,38 @@ ImageToImageRCC8Calculator<TInputImage>
   ImageToImageRCC8Calculator<TInputImage>
   ::ComputeInterExterBool(void)
   {
-  /// Definition of the filters used
+    /// Definition of the filters used
     typedef itk::InvertIntensityImageFilter<BoolImageType,BoolImageType> InvertFilterType;
     typedef itk::AndImageFilter<BoolImageType,BoolImageType,BoolImageType> AndFilterType;
+ //TODELETE     typedef otb::Image<unsigned char,2> TmpImageType;
+ //TODELETE     typedef itk::CastImageFilter<BoolImageType,TmpImageType> CastFilterType;
+
+ //TODELETE     typedef ImageFileWriter<TmpImageType> WriterType;
     /// Declaration and instantiation
     typename InvertFilterType::Pointer invert = InvertFilterType::New();
     typename AndFilterType::Pointer andFilter = AndFilterType::New();
     /// The exterior is the inverted input image
+    invert->SetMaximum(true);
     invert->SetInput(m_BoolImage2);
+    
+ //TODELETE     typename CastFilterType::Pointer caster = CastFilterType::New();
+  //TODELETE    caster->SetInput(invert->GetOutput());
+ //TODELETE     typename WriterType::Pointer writer = WriterType::New();
+//TODELETE      writer->SetFileName("invert.tif");
+ //TODELETE     writer->SetInput(caster->GetOutput());
+//TODELETE      writer->Update();
+    
     andFilter->SetInput1(m_BoolImage1);
     andFilter->SetInput2(invert->GetOutput());
     andFilter->Update();
+
+ //TODELETE     caster = CastFilterType::New();
+ //TODELETE     caster->SetInput(andFilter->GetOutput());
+ //TODELETE     writer = WriterType::New();
+ //TODELETE     writer->SetFileName("and.tif");
+ //TODELETE     writer->SetInput(caster->GetOutput());
+ //TODELETE     writer->Update();
+
     /// test if the intersection is empty or not
     return IsBoolImageNotEmpty(andFilter->GetOutput());
   }
@@ -414,6 +447,7 @@ ImageToImageRCC8Calculator<TInputImage>
 	/// now
 	edgeEdgeBool = ComputeEdgeEdgeBool();
 	// otbMsgDebugMacro(<<"RCC8Calculator->GenerateData(): edgeEdge "<<edgeEdgeBool);
+  //TODELETE	std::cout<<"RCC8Calculator->GenerateData(): edgeEdge "<<edgeEdgeBool<<std::endl;
 	/// Here comes the outside knowledge
 	if(this->GetLevel1APrioriKnowledge())
 	  {
@@ -429,6 +463,7 @@ ImageToImageRCC8Calculator<TInputImage>
 	    // otbMsgDebugMacro(<<"RCC8Calculator->GenerateData(): interExter "<<interExterBool);
 	  }
 	/// At this stage we can determine if the relation is of type NTPP
+  //TODELETE	std::cout<<"RCC8Calculator->GenerateData(): interExter "<<interExterBool<<std::endl;
 	if((!interExterBool)&&(!edgeEdgeBool))
 	  {
 	    m_Value=OTB_RCC8_NTPP;
@@ -449,11 +484,13 @@ ImageToImageRCC8Calculator<TInputImage>
 		exterInterBool = ComputeExterInterBool();  
 		// otbMsgDebugMacro(<<"RCC8Calculator->GenerateData(): ExterInter "<<exterInterBool);
 	      }
+	//TODELETE      std::cout<<"RCC8Calculator->GenerateData(): ExterInter "<<exterInterBool<<std::endl;
 	    /// If it is not sufficient to compute the relation
 	    if(!ComputeRelation(edgeEdgeBool,interExterBool,exterInterBool))
 	      {
 		/// Compute the last boolean
 		interInterBool = ComputeInterInterBool();
+	 //TODELETE  	std::cout<<"RCC8Calculator->GenerateData(): InterInter "<<interInterBool<<std::endl;
 		// otbMsgDebugMacro(<<"RCC8Calculator->GenerateData(): InterInter "<<interInterBool);
 		/// Which allow the full determination
 		if ((interExterBool)&&(edgeEdgeBool)&&(exterInterBool)&&(!interInterBool))
diff --git a/Code/SpatialReasoning/otbPolygonToPolygonRCC8Calculator.h b/Code/SpatialReasoning/otbPolygonToPolygonRCC8Calculator.h
new file mode 100644
index 0000000000..cee52a90f1
--- /dev/null
+++ b/Code/SpatialReasoning/otbPolygonToPolygonRCC8Calculator.h
@@ -0,0 +1,130 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef _otbPolygonToPolygonRCC8Calculator_h
+#define _otbPolygonToPolygonRCC8Calculator_h
+
+#include "itkObject.h"
+#include "otbRCC8Value.h"
+#include "otbImage.h"
+
+namespace otb
+{
+/**
+ * \class PolygonToPolygonRCC8Calculator
+ * \brief This class compute the RCC8 relation between the regions from two segmentation images.
+ *
+ * The RCC8 system comes from qualitative spatial reasoning. 
+ * It is a set of pairwise disjoint exhaustive relation between two closed region of space.
+ * There are 8 possible relations :
+ * DC: Disconnected
+ * EC: Externaly connected
+ * PO: Partial overlap
+ * TPP: Tangential proper part
+ * NTPP: Non tangential proper part
+ * TPPI: Tangential proper part inverse
+ * NTPPI: Non tangential proper part inverse
+ * EQ: Equivalence
+ *
+ * The goal of this class is to determine which of these 8 relations link the two inputs regions represented
+ * by the closed input path. Since this class will further be used iteratively on a possibly large set 
+ * of regiosn, it is optimised : the decision is managed by a decision tree.
+ */
+template <class TInputPolygon>            
+  class ITK_EXPORT PolygonToPolygonRCC8Calculator : public itk::Object
+{
+public:
+  /** Standard class typedefs. */
+  typedef PolygonToPolygonRCC8Calculator Self;
+  typedef itk::Object  Superclass;
+  typedef itk::SmartPointer<Self>   Pointer;
+  typedef itk::SmartPointer<const Self>  ConstPointer;
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(PolygonToPolygonRCC8Calculator,Object);
+  /** Types definitions for the input image. */
+  typedef TInputPolygon                      PolygonType;
+  typedef typename PolygonType::Pointer      PolygonPointerType;
+  typedef typename PolygonType::ConstPointer PolygonConstPointerType;
+  typedef typename PolygonType::VertexListType    VertexListType;
+  typedef typename PolygonType::ContinuousIndexType ContinuousIndexType;
+  typedef typename VertexListType::ConstIterator VertexListIteratorType;
+  typedef std::vector<bool> BoolVectorType;
+
+  /** RCC8 values type */
+  typedef RCC8Value RCC8ValueType;
+
+  /**
+   * Get the RCC8 relation.
+   * \return The RCC8 relation value.
+   */
+  RCC8ValueType GetValue(void);
+
+  /** Set external knowledge to help the decision process */
+  itkSetMacro(Level1APrioriKnowledge,bool);
+  itkSetMacro(Level3APrioriKnowledge,bool);
+  itkGetMacro(Level1APrioriKnowledge,bool);
+  itkGetMacro(Level3APrioriKnowledge,bool);
+ 
+  itkSetObjectMacro(Polygon1,PolygonType);
+  itkSetObjectMacro(Polygon2,PolygonType);
+  itkGetObjectMacro(Polygon1,PolygonType);
+  itkGetObjectMacro(Polygon2,PolygonType);
+  
+  /** Main computation method */
+  void Compute(void);
+  
+  virtual bool ComputeRelation(bool edgeEdgeBool, bool interExterBool, bool exterInterBool);
+
+  virtual bool ComputeInterExter(PolygonPointerType path1,PolygonPointerType path2);
+
+  virtual bool ComputeEdgeEdge(PolygonPointerType path1, PolygonPointerType path2);
+  
+  virtual bool ComputeInterInter(PolygonPointerType path1, PolygonPointerType path2);
+
+  
+  protected:
+  /** Constructor */
+  PolygonToPolygonRCC8Calculator();
+  /** Destructor */
+  virtual ~PolygonToPolygonRCC8Calculator() {};
+  /** PrintSelf method */
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+ private:
+  /** The RCC8 relation value */
+  RCC8ValueType m_Value;
+  /**  Decision tree Level 1 A priori knowledge */
+  bool m_Level1APrioriKnowledge;
+  /**  Decision tree Level 3 A priori knowledge */
+  bool m_Level3APrioriKnowledge;
+  /** Polygon of region 1 */
+  PolygonPointerType m_Polygon1;
+  /** Polygon of region 2 */
+  PolygonPointerType m_Polygon2;
+  /** Epsilon */
+  double m_Epsilon;
+
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbPolygonToPolygonRCC8Calculator.txx"
+#endif
+
+#endif 
diff --git a/Code/SpatialReasoning/otbPolygonToPolygonRCC8Calculator.txx b/Code/SpatialReasoning/otbPolygonToPolygonRCC8Calculator.txx
new file mode 100644
index 0000000000..a8a26e32ab
--- /dev/null
+++ b/Code/SpatialReasoning/otbPolygonToPolygonRCC8Calculator.txx
@@ -0,0 +1,319 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef _otbPolygonToPolygonRCC8Calculator_txx
+#define _otbPolygonToPolygonRCC8Calculator_txx
+
+#include "otbPolygonToPolygonRCC8Calculator.h"
+#include "otbMacro.h"
+
+namespace otb
+{     
+/**
+ * Constructor
+ */
+template<class TInputPolygon>
+PolygonToPolygonRCC8Calculator<TInputPolygon>
+::PolygonToPolygonRCC8Calculator()
+{
+  m_Value        = OTB_RCC8_DC;
+  m_Level1APrioriKnowledge=false;
+  m_Level3APrioriKnowledge=false;
+ }
+/**
+ * Get the RCC8 relation.
+ * \return The RCC8 relation value.
+ */
+template <class TInputPolygon>
+typename PolygonToPolygonRCC8Calculator<TInputPolygon>
+::RCC8ValueType
+PolygonToPolygonRCC8Calculator<TInputPolygon>
+::GetValue(void)
+{
+  return m_Value;
+}
+
+template<class TInputPolygon>
+void
+PolygonToPolygonRCC8Calculator<TInputPolygon>
+::Compute(void)
+{
+  bool edgeEdgeBool,interExterBool,exterInterBool,interInterBool;
+  /// The boolean edgeEdge is needed in each case, so it si computed
+  /// now
+  edgeEdgeBool = ComputeEdgeEdge(m_Polygon1,m_Polygon2);
+
+  //std::cout<<"EdgeEdge: "<<edgeEdgeBool<<std::endl;
+
+  if(this->GetLevel1APrioriKnowledge())
+    {
+      interExterBool=true;
+    }
+  else
+    {
+      /// Else it must be computed
+      interExterBool = ComputeInterExter(m_Polygon1,m_Polygon2);
+    }
+  
+  //std::cout<<"InterExter: "<<interExterBool<<std::endl;
+ 
+  /// At this stage we can determine if the relation is of type NTPP
+  if((!interExterBool)&&(!edgeEdgeBool))
+    {
+      m_Value=OTB_RCC8_NTPP;
+    }
+  else
+    {
+      /// If not, we must consider the intersection between exterior
+      if(this->GetLevel3APrioriKnowledge())
+	{
+	  /// If the Level3APRioriKnowledge flag is set, this boolean
+	  /// can be determined from the two others
+	  exterInterBool=true;
+	}
+      else
+	{
+	  /// Else it must be computed
+	  exterInterBool = ComputeInterExter(m_Polygon2,m_Polygon1);  
+	}
+
+      //std::cout<<"ExterInter: "<<exterInterBool<<std::endl;
+
+      /// If it is not sufficient to compute the relation
+      if(!ComputeRelation(edgeEdgeBool,interExterBool,exterInterBool))
+	{
+	  /// Compute the last boolean
+	  interInterBool = ComputeInterInter(m_Polygon1,m_Polygon2);
+
+	  //std::cout<<"InterInter: "<<interInterBool<<std::endl;
+
+	  /// Which allow the full determination
+	  if ((interExterBool)&&(edgeEdgeBool)&&(exterInterBool)&&(!interInterBool))
+	    {
+	      m_Value=OTB_RCC8_EC;
+	    }
+	  else
+	    {
+	      m_Value=OTB_RCC8_PO;
+	    }
+	}
+    }
+}
+template<class TInputPolygon>
+bool 
+PolygonToPolygonRCC8Calculator<TInputPolygon>
+::ComputeRelation(bool edgeEdgeBool, bool interExterBool, bool exterInterBool)
+{
+  // This decision process is based on a decision tree
+  if ((!interExterBool)&&(edgeEdgeBool)&&(!exterInterBool))
+    {
+      m_Value=OTB_RCC8_EQ;
+      return true;
+    }
+  else if ((!interExterBool)&&(edgeEdgeBool)&&(exterInterBool))
+    {
+      m_Value=OTB_RCC8_TPP;
+      return true;
+    }
+  else if ((interExterBool)&&(!edgeEdgeBool)&&(!exterInterBool))
+    {
+      m_Value=OTB_RCC8_NTPPI;
+      return true;
+    }
+  else if ((interExterBool)&&(!edgeEdgeBool)&&(exterInterBool))
+    {
+      m_Value=OTB_RCC8_DC;
+      return true;
+    }
+  else if ((interExterBool)&&(edgeEdgeBool)&&(!exterInterBool))
+    {
+      m_Value=OTB_RCC8_TPPI;
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+template<class TInputPolygon>
+bool
+PolygonToPolygonRCC8Calculator<TInputPolygon>
+::ComputeInterExter(PolygonPointerType polygon1, PolygonPointerType polygon2)
+{
+  bool resp = false;
+  VertexListIteratorType it = polygon1->GetVertexList()->Begin();
+  VertexListIteratorType it_end = polygon1->GetVertexList()->End();
+ 
+  ContinuousIndexType current = it.Value();
+  ContinuousIndexType first = current;
+  bool isInside = polygon2->IsInside(current);
+  bool firstIsInside = isInside;
+  bool isExterior = !isInside && !polygon2->IsOnEdge(current);
+
+  //std::cout<<current<<" is inside: "<<isInside<<std::endl;
+  //std::cout<<current<<" is on edge: "<<polygon2->IsOnEdge(current)<<std::endl;
+
+  unsigned int index = 0;
+  if(isExterior)
+    {
+      resp = true;
+    }
+  ++it;
+  while (!resp && it != it_end)
+    {
+      bool nextIsInside = polygon2->IsInside(it.Value());
+
+      if (isInside && nextIsInside)
+	{
+	  //std::cout<<current<<" is inside and "<<it.Value()<<" is inside, nb crossings: "<<polygon2->NbCrossing(current,it.Value())<<std::endl;
+	  resp = polygon2->NbCrossing(current,it.Value()) >0;
+	}
+      current = it.Value();
+      isInside  = nextIsInside;
+      isExterior = !isInside && !polygon2->IsOnEdge(current) ;
+      //std::cout<<current<<" is inside: "<<isInside<<std::endl;
+      //std::cout<<current<<" is on edge: "<<polygon2->IsOnEdge(current)<<std::endl;
+       if(isExterior)
+	 {
+	   resp = true;
+	 }
+
+       ++index;
+       ++it;
+    }
+
+  if(!resp && isInside && firstIsInside)
+    {
+      resp = polygon2->NbCrossing(current,first)>0;
+      //std::cout<<current<<" is inside and "<<first<<" is inside, nb crossings: "<<polygon2->NbCrossing(current,first)<<std::endl;
+    }
+
+  return resp;
+}
+
+
+template<class TInputPolygon>
+bool
+PolygonToPolygonRCC8Calculator<TInputPolygon>
+::ComputeInterInter(PolygonPointerType polygon1, PolygonPointerType polygon2)
+{
+  bool resp = false;
+  VertexListIteratorType it = polygon1->GetVertexList()->Begin();
+  VertexListIteratorType it_end = polygon1->GetVertexList()->End();
+  ContinuousIndexType current = it.Value();
+  ContinuousIndexType first = current;
+  bool currentIsInside = polygon2->IsInside(current);
+  bool firstIsInside = currentIsInside;
+
+  if(currentIsInside)
+    {
+      resp = true;
+    }
+  ++it;
+  while (!resp && it != it_end)
+    {
+      bool nextIsInside = polygon2->IsInside(it.Value());
+
+      if (!currentIsInside && !nextIsInside && !polygon2->IsOnEdge(current) && !polygon2->IsOnEdge(it.Value()))
+	{
+	  unsigned int nbCrossings = polygon2->NbCrossing(current,it.Value());
+
+	  resp = nbCrossings>0;
+	}
+       currentIsInside =nextIsInside;
+       current = it.Value();
+       
+       if(currentIsInside)
+	 {
+	   resp = true;
+	 }
+      ++it;
+    }
+  
+    if (!resp && !currentIsInside && !firstIsInside && !polygon2->IsOnEdge(current) && !polygon2->IsOnEdge(first))
+	{
+	  unsigned int nbCrossings = polygon2->NbCrossing(current,first);
+
+	  resp = nbCrossings>0;
+	}
+  return resp;
+}
+template<class TInputPolygon>
+bool
+PolygonToPolygonRCC8Calculator<TInputPolygon>
+::ComputeEdgeEdge(PolygonPointerType polygon1, PolygonPointerType polygon2)
+{
+  bool resp = false;
+  VertexListIteratorType it = polygon1->GetVertexList()->Begin();
+  VertexListIteratorType it_end = polygon1->GetVertexList()->End();
+
+  ContinuousIndexType current = it.Value();
+  resp = polygon2->IsOnEdge(current);
+  //std::cout<<"IsOnEdge: "<<current<<": "<<polygon2->IsOnEdge(current)<<std::endl;
+  ContinuousIndexType first = current; 
+  ++it;
+  
+  while (! resp && it != it_end)
+    {
+      if(polygon2->NbTouching(current,it.Value())>0)
+	{
+	  resp = true;
+	  //std::cout<<"NbCrossing: "<<current<<" -> "<<it.Value()<<": "<<polygon2->NbCrossing(current,it.Value())<<std::endl;
+	}
+      if(polygon2->NbCrossing(current,it.Value())>0)
+	{
+	  resp = true;
+	  //std::cout<<"NbTouching: "<<current<<" -> "<<it.Value()<<": "<<polygon2->NbTouching(current,it.Value())<<std::endl;
+	}
+      current = it.Value();
+      
+      if(polygon2->IsOnEdge(current))
+	{
+	  resp = true;
+	  //std::cout<<"IsOnEdge: "<<current<<": "<<polygon2->IsOnEdge(current)<<std::endl;
+	}
+       ++it;
+    }
+  if(!resp && polygon2->NbTouching(current,first)>0)
+    {
+      resp = true;
+      //std::cout<<"NbCrossing: "<<current<<" -> "<<first<<": "<<polygon2->NbCrossing(current,first)<<std::endl;
+    }
+  if(polygon2->NbCrossing(current,first)>0)
+    {
+      resp = true;
+      //std::cout<<"NbTouching: "<<current<<" -> "<<first<<": "<<polygon2->NbTouching(current,first)<<std::endl;
+    }
+ 
+  return resp;
+}
+/**
+ * PrintSelf method
+ */
+template<class TInputPolygon>
+void
+PolygonToPolygonRCC8Calculator<TInputPolygon>
+::PrintSelf( std::ostream& os,itk::Indent indent ) const
+{
+  Superclass::PrintSelf(os,indent);
+}
+} // end namespace otb
+
+#endif
+
+
diff --git a/Code/SpatialReasoning/otbRCC8Graph.h b/Code/SpatialReasoning/otbRCC8Graph.h
index 5f0995eaeb..5a74837c7f 100644
--- a/Code/SpatialReasoning/otbRCC8Graph.h
+++ b/Code/SpatialReasoning/otbRCC8Graph.h
@@ -30,15 +30,7 @@ namespace otb
 /**
  * \class RCC8Graph
  * \brief This class is a data structure designed to store RCC8 Graph
- * computed from a pyramidal segmentation. It is divided in two
- * components :
- * An internal graph object which uses the boost graph library
- * implementation, using RCC8GraphEdgeProperties for edges properties
- * and RCC8GraphVerticesProperties for vertices properties.
- * A list of segmentation images resulting from the pyramidal
- * segmentation. These use a label pixel type, and each region is
- * referenced from in the graph vertex properties via its
- * RegionIndexInImage parameter.
+ * computed from a pyramidal segmentation.
  *
  * A batch of boost operation has been embedded in order to provide
  * basic functionnality such as adding a new edge, or retrieving the
@@ -48,7 +40,7 @@ namespace otb
  * applications, one should provide a patch for this class including
  * the new functionnalities, for consistency reason.
  */
-template <class TVertex, class TSegmentationImage = Image< typename TVertex::LabelType,2> >  
+template <class TVertex>  
 class ITK_EXPORT RCC8Graph  :
     public itk::DataObject
 {
@@ -77,19 +69,9 @@ class ITK_EXPORT RCC8Graph  :
   typedef typename InternalGraphType::vertex_descriptor  VertexDescriptorType;
   typedef typename InternalGraphType::edge_descriptor    EdgeDescriptorType;
 
-  /** Segmentation images typedef */
-  typedef TSegmentationImage SegmentationImageType;
-  typedef typename SegmentationImageType::Pointer SegmentationImagePointerType;
-  typedef ImageList<SegmentationImageType> SegmentationImageListType;
-  typedef typename SegmentationImageListType::Pointer SegmentationImageListPointerType;
-
   /** Getters and Setters for the number of vertices */
   itkSetMacro(NumberOfVertices,unsigned int);
   itkGetConstReferenceMacro(NumberOfVertices,unsigned int);
-
-  /** Get and set the internal image list */
-  itkSetObjectMacro(SegmentationImageList,SegmentationImageListType);
-  itkGetObjectMacro(SegmentationImageList,SegmentationImageListType);
   
   /**
    *  Return the internal boost graph object.
@@ -126,11 +108,7 @@ class ITK_EXPORT RCC8Graph  :
    * /return The number of edges.
    */
   unsigned int GetNumberOfEdges(void);
-  /**
-   * Get the number of segmentation images
-   * \return the number of segmentation images
-   */
-  unsigned int GetNumberOfSegmentationImages(void);
+
 protected:
   /** Constructor */
   RCC8Graph();
@@ -150,8 +128,6 @@ private:
   unsigned int m_NumberOfVertices;
   /** Internal representation using the boost graph library */
   InternalGraphType m_Graph;
-  /** The segmentation image list associated with the graph */
-  SegmentationImageListPointerType m_SegmentationImageList;
 };
 } // end namespace otb
 
diff --git a/Code/SpatialReasoning/otbRCC8Graph.txx b/Code/SpatialReasoning/otbRCC8Graph.txx
index 6fad57a23e..83cfb5d10c 100644
--- a/Code/SpatialReasoning/otbRCC8Graph.txx
+++ b/Code/SpatialReasoning/otbRCC8Graph.txx
@@ -23,21 +23,20 @@ namespace otb
   /** 
    * Constructor 
    */
-  template <class TVertex, class TSegmentationImage>
-  RCC8Graph<TVertex, TSegmentationImage>
+  template <class TVertex>
+  RCC8Graph<TVertex>
   ::RCC8Graph()
   {
     m_NumberOfVertices = 0;
-    m_SegmentationImageList = SegmentationImageListType::New();
   };
   /**
    * since the number of vertices is mandatory to instantiate the
    * internal boost representation, the build method has to be called
    * once this parameter is set.
    */
-  template <class TVertex, class TSegmentationImage>
+  template <class TVertex>
   void 
-  RCC8Graph<TVertex, TSegmentationImage>
+  RCC8Graph<TVertex>
   ::Build(void)
   {
     this->Initialize(m_NumberOfVertices-1);
@@ -46,9 +45,9 @@ namespace otb
    * Initialize a range of vertex.
    * \param num The index of the last vertices to intialize.
    */
-  template <class TVertex, class TSegmentationImage>
+  template <class TVertex>
   void 
-  RCC8Graph<TVertex, TSegmentationImage>
+  RCC8Graph<TVertex>
   ::Initialize( unsigned int num)
   {
     for(unsigned int i = boost::num_vertices(m_Graph); i<=num;i++)
@@ -63,9 +62,9 @@ namespace otb
    * \param index The index of the vertex in the graph.
    * \param vertex The vertex to set.
    */
-  template<class TVertex, class TSegmentationImage>
+  template<class TVertex>
   void
-  RCC8Graph<TVertex, TSegmentationImage>
+  RCC8Graph<TVertex>
   ::SetVertex(unsigned int index, VertexPointerType vertex)
   {
     if(index>=m_NumberOfVertices)
@@ -81,10 +80,10 @@ namespace otb
    * \param index The index of the vertex in the graph
    * \return The vertex.
    */
-  template <class TVertex, class TSegmentationImage>
-  typename RCC8Graph<TVertex, TSegmentationImage>
+  template <class TVertex>
+  typename RCC8Graph<TVertex>
   ::VertexPointerType
-  RCC8Graph<TVertex, TSegmentationImage>
+  RCC8Graph<TVertex>
   ::GetVertex(unsigned int index)
   {
     VertexDescriptorType v = *boost::vertices(m_Graph).first;
@@ -96,9 +95,9 @@ namespace otb
    * \param index2 The index of the target vertex.
    * \param r The rcc8 value associated to the edge.
    */
-  template <class TVertex, class TSegmentationImage>
+  template <class TVertex>
   void
-  RCC8Graph<TVertex, TSegmentationImage>
+  RCC8Graph<TVertex>
   ::AddEdge(unsigned int index1, unsigned int index2, RCC8ValueType r)
   {
     EdgeDescriptorType e = boost::add_edge(index1,index2,m_Graph).first;
@@ -110,30 +109,19 @@ namespace otb
    * Get number of edges
    * /return The number of edges.
    */
-  template <class TVertex, class TSegmentationImage>
+  template <class TVertex>
   unsigned int
-  RCC8Graph<TVertex, TSegmentationImage>
+  RCC8Graph<TVertex>
   ::GetNumberOfEdges(void)
   {
     return num_edges(m_Graph);
   }
-  /**
-   * Get the number of segmentation images
-   * \return the number of segmentation images
-   */
-  template <class TVertex, class TSegmentationImage>
-  unsigned int
-  RCC8Graph<TVertex, TSegmentationImage>
-  ::GetNumberOfSegmentationImages(void)
-  {
-    return m_SegmentationImageList->Size();
-  }
   /**
    * PrintSelf method
    */
-  template <class TVertex, class TSegmentationImage>
+  template <class TVertex>
   void
-  RCC8Graph<TVertex, TSegmentationImage>
+  RCC8Graph<TVertex>
   ::PrintSelf( std::ostream& os,itk::Indent indent ) const
   {
     Superclass::PrintSelf(os,indent);
diff --git a/Code/SpatialReasoning/otbRCC8GraphFileReader.h b/Code/SpatialReasoning/otbRCC8GraphFileReader.h
index 878c84365b..047252695d 100644
--- a/Code/SpatialReasoning/otbRCC8GraphFileReader.h
+++ b/Code/SpatialReasoning/otbRCC8GraphFileReader.h
@@ -21,8 +21,6 @@
 #include "otbRCC8GraphSource.h"
 #include "itkExceptionObject.h"
 
-#include "otbImageFileReader.h"
-
 namespace otb
 {
 /** \class RCC8GraphFileReaderException
@@ -57,15 +55,6 @@ public:
  * and ParseVertex. The ParseVertex use builds an AttributesMap and pass it to a new
  * vertex.
  *
- * The flag ReadSegmentationImages enable or disable the reading of the segmentation images.
- * If this is enabled, the RCC8GraphFileReader will look for image files with the same name
- * than the graph filename, concatenated with the segmentation image index, and the image extension.
- *
- * For instance, if the graph file is "graph.dot", and the image extension "tif", and if the graph comes
- * from 6 segmentations image (information extracted from the Vertices properties), the reader will look for
- * image files named graph1.tif, graph2.tif ..., graph6.tif. If one of the segmentation image is missing, none of
- * them are loaded into the graph object output.
- *
  * \sa RCC8GraphFileWriter
  * \sa RCC8Graph
  */
@@ -88,25 +77,11 @@ public:
   typedef typename OutputGraphType::VertexType VertexType;
   typedef typename VertexType::Pointer VertexPointerType;
   typedef typename OutputGraphType::RCC8ValueType RCC8ValueType;
-  typedef typename OutputGraphType::SegmentationImageType SegmentationImageType;
-  typedef typename OutputGraphType::SegmentationImagePointerType SegmentationImagePointerType;
-  typedef typename OutputGraphType::SegmentationImageListType SegmentationImageListType;
-  typedef typename OutputGraphType::SegmentationImageListPointerType SegmentationImageListPointerType;
-  typedef ImageFileReader<SegmentationImageType> SegmentationImageReaderType;
-  typedef typename SegmentationImageReaderType::Pointer SegmentationImageReaderPointerType;
 
   /** Set the filename  */
   itkSetStringMacro(FileName);
   /** Get the filename */
   itkGetStringMacro(FileName);
-  /** Flag to enable/Disable the reading of segmentation images */
-  itkSetMacro(ReadSegmentationImages,bool);
-  itkGetMacro(ReadSegmentationImages,bool);
-  itkBooleanMacro(ReadSegmentationImages);
-  /** Set the segmentation image extension */
-  itkSetStringMacro(ImageExtension);
-  /** Get the segmentation image extension */
-  itkGetStringMacro(ImageExtension);
 
 protected:
   /** Constructor */
@@ -125,14 +100,13 @@ protected:
    * \param line The line to parse.
    */
   void  ParseVertex(std::string line);
+  
   /** PrintSelf method */
   virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
-
+  
  private:
   /** File name */
   std::string m_FileName;
-  std::string m_ImageExtension;
-  bool m_ReadSegmentationImages;
 };
 }
 #ifndef OTB_MANUAL_INSTANTIATION
diff --git a/Code/SpatialReasoning/otbRCC8GraphFileReader.txx b/Code/SpatialReasoning/otbRCC8GraphFileReader.txx
index e522529b95..fb58d49ccc 100644
--- a/Code/SpatialReasoning/otbRCC8GraphFileReader.txx
+++ b/Code/SpatialReasoning/otbRCC8GraphFileReader.txx
@@ -34,8 +34,6 @@ RCC8GraphFileReader<TOutputGraph>
 ::RCC8GraphFileReader()
 {
   m_FileName="";
-  m_ImageExtension=".tif";
-  m_ReadSegmentationImages = true;
 }
 /**
  * Destructor
@@ -98,6 +96,7 @@ RCC8GraphFileReader<TOutputGraph>
   vertex->SetAttributesMap(attr);
   this->GetOutput()->SetVertex(index,vertex);
 }
+
 /**
  * Generate data method
  */
@@ -106,7 +105,6 @@ void
 RCC8GraphFileReader<TOutputGraph>
 ::GenerateData()
 {  
-  otbMsgDevMacro(<<"RCC8GraphFileWriter: Call to the GenerateData method");
   std::ifstream fin;
   std::string line;
   
@@ -141,38 +139,6 @@ RCC8GraphFileReader<TOutputGraph>
 	}
     }
   fin.close();
-
-  // if the reading of the segmentation images is enabled
-  if(m_ReadSegmentationImages)
-    {
-      unsigned int nImages = 0;
-      // first find the number of segmentation images to look for
-      RCC8VertexIterator<OutputGraphType> it(this->GetOutput());
-      for(it.GoToBegin();!it.IsAtEnd();++it)
-	{
-	  if(nImages<it.Get()->GetSegmentationImageIndex())
-	    {
-	      nImages=it.Get()->GetSegmentationImageIndex();
-	    }
-	}
-      nImages = nImages+1;
-      std::string prefix = m_FileName.substr(0,m_FileName.length()-4);
-      
-      itk::OStringStream oss;
-
-      // then read the images
-      for(unsigned int i=1;i<=nImages;++i)
-	{
-	  oss.str("");
-	  oss<<prefix<<i<<m_ImageExtension;
-	  
-	  SegmentationImageReaderPointerType reader = SegmentationImageReaderType::New();
-	  reader->SetFileName(oss.str().c_str());
-	  // may be supressed
-	  reader->Update();
-	  this->GetOutput()->GetSegmentationImageList()->PushBack(reader->GetOutput());
-	}
-    }
 }
 /**
  * PrintSelf method
diff --git a/Code/SpatialReasoning/otbRCC8GraphFileWriter.h b/Code/SpatialReasoning/otbRCC8GraphFileWriter.h
index 5325c5a424..6d074f7572 100644
--- a/Code/SpatialReasoning/otbRCC8GraphFileWriter.h
+++ b/Code/SpatialReasoning/otbRCC8GraphFileWriter.h
@@ -21,7 +21,6 @@
 #include "itkProcessObject.h"
 #include "itkExceptionObject.h"
 #include "otbRCC8Graph.h"
-#include "otbImageFileWriter.h"
 
 namespace otb
 {
@@ -83,23 +82,11 @@ public:
   typedef typename InputGraphType::VertexDescriptorType VertexDescriptorType;
   typedef typename InputGraphType::RCC8ValueType RCC8ValueType;
   typedef typename VertexType::AttributesMapType AttributesMapType;
-  typedef typename InputGraphType::SegmentationImageType SegmentationImageType;
-  typedef typename SegmentationImageType::Pointer SegmentationImagePointerType;
-  typedef ImageFileWriter<SegmentationImageType> SegmentationImageWriterType;
-  typedef typename SegmentationImageWriterType::Pointer SegmentationImageWriterPointerType;
 
   /** Set the filename */
   itkSetStringMacro(FileName);
   /** Get the filename */
   itkGetStringMacro(FileName);
-  /** Set the segmentation images suffix */
-  itkSetStringMacro(ImageExtension);
-  /** Get the segmentation images suffix */
-  itkGetStringMacro(ImageExtension);
-  /** Wether to write segmentation images or not */
-  itkSetMacro(WriteSegmentationImages,bool);
-  itkGetMacro(WriteSegmentationImages,bool);
-  itkBooleanMacro(WriteSegmentationImages);
   /**
    * Set the input graph.
    * \param inputGraph The graph to write.
@@ -154,10 +141,6 @@ protected:
 private:
   /** Filename of the graph file to write */
   std::string m_FileName;
-  /** Wether to write segmentation images or not */
-  bool m_WriteSegmentationImages;
-  /** The segmentation images suffix */
-  std::string m_ImageExtension;
 };
 } // namespace otb
 
diff --git a/Code/SpatialReasoning/otbRCC8GraphFileWriter.txx b/Code/SpatialReasoning/otbRCC8GraphFileWriter.txx
index 69bd272c7b..597ab592f9 100644
--- a/Code/SpatialReasoning/otbRCC8GraphFileWriter.txx
+++ b/Code/SpatialReasoning/otbRCC8GraphFileWriter.txx
@@ -35,8 +35,6 @@ RCC8GraphFileWriter<TInputGraph>
 {
   this->SetNumberOfRequiredInputs(1);
   m_FileName = "";
-  m_ImageExtension = ".tif";
-  m_WriteSegmentationImages = true;
 }
 /**
  * Destructor
@@ -150,16 +148,10 @@ RCC8GraphFileWriter<TInputGraph>
   out<<"digraph G {"<<std::endl;
 
   // For each vertex in the graph
-  unsigned int maxSegImageIndex = 0;
-
   VertexIteratorType vIt(input);
   for(vIt.GoToBegin();!vIt.IsAtEnd();++vIt)
     {
       this->WriteVertex(out,vIt.GetIndex(),vIt.Get());
-      if(maxSegImageIndex<vIt.Get()->GetSegmentationImageIndex())
-	{
-	  maxSegImageIndex = vIt.Get()->GetSegmentationImageIndex();
-	}
     }
 
   // For each edge in the graph
@@ -176,27 +168,6 @@ RCC8GraphFileWriter<TInputGraph>
 
   // Close the file
   out.close();
-
-  // Write the segmentation images 
-  if(m_WriteSegmentationImages)
-    {
-
-      std::string prefix = m_FileName.substr(0,m_FileName.length()-4);
-      
-      itk::OStringStream oss;
-
-      // then read the images
-      for(unsigned int i=1;i<=maxSegImageIndex+1;++i)
-	{
-	  oss.str("");
-	  oss<<prefix<<i<<m_ImageExtension;
-	  
-	  SegmentationImageWriterPointerType writer = SegmentationImageWriterType::New();
-	  writer->SetFileName(oss.str().c_str());
-	  writer->SetInput(this->GetInput()->GetSegmentationImageList()->GetNthElement(i-1));
-	  writer->Update();
-	}
-    }
 }
 /**
  * Write an edge to file.
diff --git a/Code/SpatialReasoning/otbRCC8VertexBase.h b/Code/SpatialReasoning/otbRCC8VertexBase.h
index 42a7abe763..988ccc7b7e 100644
--- a/Code/SpatialReasoning/otbRCC8VertexBase.h
+++ b/Code/SpatialReasoning/otbRCC8VertexBase.h
@@ -31,7 +31,7 @@ namespace otb
  *
  * \sa RCC8Graph, RCC8Edge
  */
-template <class TLabel>
+template <class TPath>
 class ITK_EXPORT RCC8VertexBase 
 : public itk::DataObject
 {
@@ -46,17 +46,21 @@ class ITK_EXPORT RCC8VertexBase
   /** Run-time type information (and related methods). */
   itkTypeMacro(RCC8VertexBase,DataObject);
   /** Input image associated typedefs*/
-  typedef TLabel LabelType;
+  typedef TPath PathType;
+  typedef typename PathType::Pointer PathPointerType;
+  typedef typename PathType::ContinuousIndexType ContinuousIndexType;
   
   /** char* vector attributes */
   typedef std::map<std::string,std::string> AttributesMapType;
  
   /** Segmentation image index accessors */
-  itkGetMacro(SegmentationImageIndex,unsigned int);
-  itkSetMacro(SegmentationImageIndex,unsigned int);
+  itkGetMacro(SegmentationLevel,unsigned int);
+  itkSetMacro(SegmentationLevel,unsigned int);
+ itkGetMacro(SegmentationType,bool);
+  itkSetMacro(SegmentationType,bool);
   /** Object label in image accessor */
-  itkGetMacro(ObjectLabelInImage,LabelType);
-  itkSetMacro(ObjectLabelInImage,LabelType);
+  itkGetObjectMacro(Path,PathType);
+  itkSetObjectMacro(Path,PathType);
   /**
    * Set the VertexBase attributes from the attributes vector.
    * \param attributes The vector containing the parsed attributes.
@@ -77,10 +81,12 @@ protected:
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
 
  private:
-  /** The segmentation image index */
-  unsigned int m_SegmentationImageIndex;
-  /** The label of the object in the segmentation image */
-  LabelType  m_ObjectLabelInImage;
+  /** The segmentation level */
+  unsigned int m_SegmentationLevel;
+  /** True if bright details, false otherwise */
+  bool m_SegmentationType;
+  /** The path of the edge of the region */
+  PathPointerType  m_Path;
 };
 } // end namespace otb
 #ifndef OTB_MANUAL_INSTANTIATION
diff --git a/Code/SpatialReasoning/otbRCC8VertexBase.txx b/Code/SpatialReasoning/otbRCC8VertexBase.txx
index 9fcb80d967..c0ae5c7d18 100644
--- a/Code/SpatialReasoning/otbRCC8VertexBase.txx
+++ b/Code/SpatialReasoning/otbRCC8VertexBase.txx
@@ -25,55 +25,98 @@ namespace otb
 /**
  * Constructor
  */
-template <class TLabel>
-RCC8VertexBase<TLabel>
+template <class TPath>
+RCC8VertexBase<TPath>
 ::RCC8VertexBase()
 {
-  m_SegmentationImageIndex=0;
-  m_ObjectLabelInImage=0;
+  m_SegmentationLevel=0;
+  m_SegmentationType= true;
+  m_Path = PathType::New();
+  m_Path->Initialize();
 }
 /**
  * Set the VertexBase attributes from the attributes vector.
  * \param attributes The vector containing the parsed attributes.
  */
-template <class TLabel>
+template <class TPath>
 void
-RCC8VertexBase<TLabel>
+RCC8VertexBase<TPath>
 ::SetAttributesMap(AttributesMapType attributes)
 {
-  m_SegmentationImageIndex=static_cast<unsigned int>(atoi(attributes["SegmentationImageIndex"].c_str()));
-  m_ObjectLabelInImage=static_cast<LabelType>(atof(attributes["ObjectLabelInImage"].c_str()));
+  m_SegmentationLevel=static_cast<unsigned int>(atoi(attributes["SegmentationLevel"].c_str()));
+  m_SegmentationType=static_cast<bool>(atoi(attributes["SegmentationType"].c_str()));
+  unsigned int nbPoints =static_cast<unsigned int>(atoi(attributes["NumberOfPointsInPath"].c_str()));
+
+  itk::OStringStream oss;
+
+  m_Path = PathType::New();
+  m_Path->Initialize();
+
+  for(unsigned int i = 0;i<nbPoints;++i)
+    {
+      ContinuousIndexType newPoint;
+      oss<<"P"<<i<<"x";
+      newPoint[0]=atof(attributes[oss.str()].c_str());
+      oss.str("");
+      oss<<"P"<<i<<"y";
+      newPoint[1]=atof(attributes[oss.str()].c_str());      
+      oss.str("");
+      m_Path->AddVertex(newPoint);
+    }
 }
 /**
  * Get an attributes vector representing the VertexBase attributes.
  * \return The attributes vector
  */
-template <class TLabel>
-typename RCC8VertexBase<TLabel>::AttributesMapType
-RCC8VertexBase<TLabel>
+template <class TPath>
+typename RCC8VertexBase<TPath>::AttributesMapType
+RCC8VertexBase<TPath>
 ::GetAttributesMap(void)
 {  
-  std::stringstream oss;
+  itk::OStringStream oss;
   AttributesMapType results;
-  oss<<m_SegmentationImageIndex;
-  results["SegmentationImageIndex"]=oss.str();
+  oss<<m_SegmentationLevel;
+  results["SegmentationLevel"]=oss.str();
   oss.str("");
-  oss<<static_cast<unsigned int>(m_ObjectLabelInImage);
-  results["ObjectLabelInImage"]=oss.str();
+  oss<<m_SegmentationType;
+  results["SegmentationType"]=oss.str();
   oss.str("");
+  oss<<m_Path->GetVertexList()->Size();
+  results["NumberOfPointsInPath"]=oss.str();
+  oss.str("");
+
+  typename PathType::VertexListType::ConstIterator it;
+  unsigned int index = 0;
+
+  for(it=m_Path->GetVertexList()->Begin();it!=m_Path->GetVertexList()->End();++it,++index)
+    {
+      ContinuousIndexType point = it.Value();
+      oss<<"P"<<index<<"x";
+      std::string key = oss.str();
+      oss.str("");
+      oss<<point[0];
+      results[key]=oss.str();
+      oss.str("");
+      oss<<"P"<<index<<"y";
+      key = oss.str();
+      oss.str("");
+      oss<<point[1];
+      results[key]=oss.str();
+      oss.str("");
+    } 
   return results;
 }
 /**
  * PrintSelf method
  */
-template <class TLabel>
+template <class TPath>
 void
-RCC8VertexBase<TLabel>
+RCC8VertexBase<TPath>
 ::PrintSelf( std::ostream& os,itk::Indent indent ) const
   {
     Superclass::PrintSelf(os,indent);
-    os<<indent<<"SegmentationImageIndex: "<<m_SegmentationImageIndex<<std::endl;
-    os<<indent<<"ObjectLabelInImage: "<<m_ObjectLabelInImage<<std::endl;
+    os<<indent<<"SegmentationLevel: "<<m_SegmentationLevel<<std::endl;
+    os<<indent<<"SegmentationType: "<<m_SegmentationType<<std::endl;
   }
 } // end namespace otb
 #endif
diff --git a/Code/SpatialReasoning/otbRCC8VertexWithCompacity.h b/Code/SpatialReasoning/otbRCC8VertexWithCompacity.h
index 23f123890d..7dffcba63f 100644
--- a/Code/SpatialReasoning/otbRCC8VertexWithCompacity.h
+++ b/Code/SpatialReasoning/otbRCC8VertexWithCompacity.h
@@ -29,14 +29,14 @@ namespace otb
    *  
    * \sa RCC8Graph, RCC8Edge, RCC8VertexBase
    */
-  template <class TLabel, class TPrecision = float>
+  template <class TPath, class TPrecision = float>
     class ITK_EXPORT RCC8VertexWithCompacity 
-		: public RCC8VertexBase<TLabel>
+		: public RCC8VertexBase<TPath>
     {
       public:
       /** Standard class typedefs */
       typedef RCC8VertexWithCompacity Self;
-      typedef otb::RCC8VertexBase<TLabel>  Superclass;
+      typedef otb::RCC8VertexBase<TPath>  Superclass;
       typedef itk::SmartPointer<Self>  Pointer;
       typedef itk::SmartPointer<const Self> ConstPointer;
       /** Method for creation through the object factory. */
@@ -44,7 +44,7 @@ namespace otb
       /** Run-time type information (and related methods). */
       itkTypeMacro(RCC8VertexWithCompacity,RCC8VertexBase);
       /** Input image associated typedefs*/
-      typedef TLabel LabelType;
+      typedef TPath PathType;
       /** Precision  typedef */
       typedef TPrecision PrecisionType;
       /** char* vector attributes */
diff --git a/Code/SpatialReasoning/otbRCC8VertexWithCompacity.txx b/Code/SpatialReasoning/otbRCC8VertexWithCompacity.txx
index 76869cc50e..e43614b1d5 100644
--- a/Code/SpatialReasoning/otbRCC8VertexWithCompacity.txx
+++ b/Code/SpatialReasoning/otbRCC8VertexWithCompacity.txx
@@ -25,8 +25,8 @@ namespace otb
 /**
  * Constructor
  */
-template <class TLabel,class TPrecision>
-RCC8VertexWithCompacity<TLabel,TPrecision>
+template <class TPath,class TPrecision>
+RCC8VertexWithCompacity<TPath,TPrecision>
 ::RCC8VertexWithCompacity()
 {
   m_Compacity=0.0;
@@ -35,9 +35,9 @@ RCC8VertexWithCompacity<TLabel,TPrecision>
  * Set the VertexWithCompacity attributes from the attributes vector.
  * \param attributes The vector containing the parsed attributes.
  */
-template <class TLabel,class TPrecision>
+template <class TPath,class TPrecision>
 void
-RCC8VertexWithCompacity<TLabel,TPrecision>
+RCC8VertexWithCompacity<TPath,TPrecision>
 ::SetAttributesMap(AttributesMapType attributes)
 {
   this->Superclass::SetAttributesMap(attributes);
@@ -47,9 +47,9 @@ RCC8VertexWithCompacity<TLabel,TPrecision>
  * Get an attributes vector representing the VertexBase attributes.
  * \return The attributes vector
  */
-template <class TLabel,class TPrecision>
-typename RCC8VertexWithCompacity<TLabel,TPrecision>::AttributesMapType
-RCC8VertexWithCompacity<TLabel,TPrecision>
+template <class TPath,class TPrecision>
+typename RCC8VertexWithCompacity<TPath,TPrecision>::AttributesMapType
+RCC8VertexWithCompacity<TPath,TPrecision>
 ::GetAttributesMap(void)
 {  
   std::stringstream oss;
@@ -63,9 +63,9 @@ RCC8VertexWithCompacity<TLabel,TPrecision>
 /**
  * PrintSelf method
  */
-template <class TLabel,class TPrecision>
+template <class TPath,class TPrecision>
 void
-RCC8VertexWithCompacity<TLabel,TPrecision>
+RCC8VertexWithCompacity<TPath,TPrecision>
 ::PrintSelf( std::ostream& os,itk::Indent indent ) const
   {
     Superclass::PrintSelf(os,indent);
-- 
GitLab