diff --git a/include/lsgrmGraphOperations.h b/include/lsgrmGraphOperations.h
index 71485c16f7819785236483e021559576ab4c651b..ea975fbe1126e6a65e0b782cdf63dda561a484d6 100644
--- a/include/lsgrmGraphOperations.h
+++ b/include/lsgrmGraphOperations.h
@@ -5,6 +5,7 @@
 #include "grmGraphOperations.h"
 #include "otbVectorImage.h"
 #include "otbMultiChannelExtractROI.h"
+#include "itkGrayscaleFillholeImageFilter.h"
 
 namespace lsgrm
 {
diff --git a/include/lsgrmGraphOperations.txx b/include/lsgrmGraphOperations.txx
index 9b11508d8680550ef1a572bd278449d40b336b72..1a64a72ab956f6f55710e88fd53fbfffab87967b 100644
--- a/include/lsgrmGraphOperations.txx
+++ b/include/lsgrmGraphOperations.txx
@@ -94,27 +94,45 @@ MergeAllGraphsAndAchieveSegmentation(
   //  // Write output graph to the output graph directory
   //  WriteGraph<TSegmenter>(segmenter.m_Graph, tmpDir, 0, 0);
 
-  // Convert graph to label image
-  typename TSegmenter::LabelImageType::Pointer labelImage = segmenter.GetLabeledClusteredOutput();
+  // Generate the label image
+  typename TSegmenter::LabelImageType::IndexType index;
+  index.Fill(0);
+  typename TSegmenter::LabelImageType::SizeType size;
+  size[0] = imageWidth;
+  size[1] = imageHeight;
+  typename TSegmenter::LabelImageType::RegionType region(index, size);
+  const typename TSegmenter::LabelImageType::InternalPixelType noDataLabel = 0;
+  typename TSegmenter::LabelImageType::Pointer labelImage = TSegmenter::LabelImageType::New();
+  labelImage->SetRegions(region);
+  labelImage->Allocate();
+  labelImage->FillBuffer(noDataLabel);
 
-  // Re-order nodes labels (left->right to top->bottom)
   using LabelImageIterator = itk::ImageRegionIterator<typename TSegmenter::LabelImageType>;
   LabelImageIterator it(labelImage, labelImage->GetLargestPossibleRegion());
-  const typename TSegmenter::LabelImageType::InternalPixelType noDataLabel = 0;
-  typename TSegmenter::LabelImageType::InternalPixelType label;
 
-  // Get the maximum label value
-  for(it.GoToBegin();!it.IsAtEnd(); ++it)
-    if (it.Get() > label)
-      label = it.Get();
+  // Start at 1 (value 0 can be used for invalid pixels)
+  unsigned int label = 1;
+  for(auto& node : segmenter.m_Graph.m_Nodes)
+    {
+    lp::CellLists borderPixels;
+    lp::ContourOperations::GenerateBorderCells(borderPixels, node->m_Contour, node->m_Id, imageWidth);
+
+    for (auto& pix: borderPixels)
+      {
+      index[0] = pix % imageWidth;
+      index[1] = pix / imageWidth;
+      labelImage->SetPixel(index, label);
+      }
+    ++label;
+    }
 
-  // Compute LUT
+  // Re-order nodes labels (left->right to top->bottom)
   vnl_vector<typename TSegmenter::LabelImageType::InternalPixelType> lut(label,noDataLabel);
   label = 1;
   for(it.GoToBegin();!it.IsAtEnd(); ++it)
     {
     unsigned int inputLabel = it.Get();
-    if (lut[ inputLabel ] == noDataLabel)
+    if (lut[ inputLabel ] == noDataLabel && inputLabel != noDataLabel)
       {
       lut[ inputLabel ] = label;
       label++;
@@ -125,8 +143,14 @@ MergeAllGraphsAndAchieveSegmentation(
   for(it.GoToBegin();!it.IsAtEnd(); ++it)
     it.Set(lut[it.Get()]);
 
-  return labelImage;
-}
+  // Fill holes
+  typedef itk::GrayscaleFillholeImageFilter<typename TSegmenter::LabelImageType,
+      typename TSegmenter::LabelImageType> FillholeFilterType;
+  typename FillholeFilterType::Pointer fillFilter = FillholeFilterType::New();
+  fillFilter->SetInput(labelImage);
+  fillFilter->Update();
+
+  return fillFilter->GetOutput();}
 
 template<class TSegmenter>
 long long unsigned int RunPartialSegmentation(const typename TSegmenter::ParamType& params,