From f6fad8b1ce9af1bd75d543d73a50e93cf2826435 Mon Sep 17 00:00:00 2001 From: remi cresson <remi.cresson@teledetection.fr> Date: Tue, 7 Nov 2017 11:12:35 +0000 Subject: [PATCH] ENH: implementation of streamed label image writing done --- app/otbLSGRM.cxx | 129 ++++++++++++--------- include/lsgrmController.h | 8 +- include/lsgrmController.txx | 28 ++--- include/lsgrmGraphOperations.h | 5 +- include/lsgrmGraphOperations.txx | 94 +++------------ include/otbStreamingGraphToImageFilter.h | 14 ++- include/otbStreamingGraphToImageFilter.txx | 95 +++++++-------- 7 files changed, 164 insertions(+), 209 deletions(-) diff --git a/app/otbLSGRM.cxx b/app/otbLSGRM.cxx index b056e67..20e9330 100644 --- a/app/otbLSGRM.cxx +++ b/app/otbLSGRM.cxx @@ -17,6 +17,10 @@ #include "lsgrmFullLambdaScheduleSegmenter.h" #include "lsgrmController.h" +// Graph to label image (streaming version) +#include "otbStreamingGraphToImageFilter.h" +#include "otbStreamingImageVirtualWriter.h" + // system tools #include <itksys/SystemTools.hxx> @@ -108,6 +112,7 @@ private: AddChoice("tiling.none", "No tiling layout"); AddParameter(ParameterType_Int, "memory", "Restrict memory use (mb)"); + MandatoryOff("memory"); } @@ -129,28 +134,28 @@ private: std::string tmpdir; if (HasValue("tmpdir")) { - tmpdir= GetParameterAsString("tmpdir"); + tmpdir= GetParameterAsString("tmpdir"); } else { - tmpdir = itksys::SystemTools::GetFilenamePath(outfname); + tmpdir = itksys::SystemTools::GetFilenamePath(outfname); } if (!tmpdir.empty()) { - // A temporary directory is specified: we check that it ends with a POSIX separator - if (tmpdir[tmpdir.size()-1] != '/') - { - // If not, we add the separator - tmpdir.append("/"); - } - - // Check that the directory exists - if (!itksys::SystemTools::FileExists(tmpdir.c_str(),false)) - { - otbAppLogFATAL("The directory " << tmpdir << " does not exist."); - } - otbAppLogINFO("Using temporary directory " << tmpdir); + // A temporary directory is specified: we check that it ends with a POSIX separator + if (tmpdir[tmpdir.size()-1] != '/') + { + // If not, we add the separator + tmpdir.append("/"); + } + + // Check that the directory exists + if (!itksys::SystemTools::FileExists(tmpdir.c_str(),false)) + { + otbAppLogFATAL("The directory " << tmpdir << " does not exist."); + } + otbAppLogINFO("Using temporary directory " << tmpdir); } @@ -163,17 +168,20 @@ private: * This function sets the generic parameters of a controller and runs the segmentation */ template<class TSegmenter> - UInt32ImageType::Pointer SetGenericParametersAndRunSegmentation(const typename TSegmenter::ParamType params){ + void + SetGenericParametersAndRunSegmentation(const typename TSegmenter::ParamType params){ // Instantiate the controller typedef typename lsgrm::Controller<TSegmenter> ControlerType; typename ControlerType::Pointer controller = ControlerType::New(); + using GraphType = typename ControlerType::GraphType; // Set specific parameters controller->SetSpecificParameters(params); // Set input image - controller->SetInputImage(GetParameterFloatVectorImage("in")); + ImageType::Pointer inputImage = GetParameterFloatVectorImage("in"); + controller->SetInputImage(inputImage); // Set threshold float thres = GetParameterFloat("threshold"); @@ -189,85 +197,92 @@ private: int inputTilingMode = GetParameterInt("tiling"); if (inputTilingMode == TILING_AUTO) { - // Automatic mode - controller->SetTilingModeAuto(); + // Automatic mode + controller->SetTilingModeAuto(); } else if (inputTilingMode == TILING_USER) { - // User mode - controller->SetTilingModeUser(); - controller->SetTileWidth(GetParameterInt("tiling.user.sizex")); - controller->SetTileHeight(GetParameterInt("tiling.user.sizey")); - controller->SetNumberOfFirstIterations(GetParameterInt("tiling.user.nfirstiter")); + // User mode + controller->SetTilingModeUser(); + controller->SetTileWidth(GetParameterInt("tiling.user.sizex")); + controller->SetTileHeight(GetParameterInt("tiling.user.sizey")); + controller->SetNumberOfFirstIterations(GetParameterInt("tiling.user.nfirstiter")); } else if (inputTilingMode == TILING_NONE) { - // None mode - controller->SetTilingModeNone(); + // None mode + controller->SetTilingModeNone(); } else { - otbAppLogFATAL("Unknown tiling mode!"); + otbAppLogFATAL("Unknown tiling mode!"); } // Input RAM value? if (HasValue("memory")) { - otbAppLogINFO("Setting maximum memory to " << GetParameterInt("memory") << " MBytes"); - controller->SetInternalMemoryAvailable(GetParameterInt("memory")); + otbAppLogINFO("Setting maximum memory to " << GetParameterInt("memory") << " MBytes"); + controller->SetInternalMemoryAvailable(GetParameterInt("memory")); } // Run the segmentation controller->RunSegmentation(); + // Prepare the label image source + typedef lsgrm::StreamingGraphToImageFilter<GraphType, UInt32ImageType> LabelImageSourceType; + typename LabelImageSourceType::Pointer labelImageSource = LabelImageSourceType::New(); + labelImageSource->SetGraph(controller->GetOutputGraph()); + labelImageSource->SetOutputSize(inputImage->GetLargestPossibleRegion().GetSize()); + labelImageSource->SetOutputOrigin(inputImage->GetOrigin()); + labelImageSource->SetOutputSpacing(inputImage->GetSpacing()); + labelImageSource->SetOutputProjectionRef(inputImage->GetProjectionRef()); + labelImageSource->GenerateOutputInformation(); + + m_LabelImageSource = static_cast<itk::ImageSource<UInt32ImageType>*>(labelImageSource); + + SetParameterOutputImage<UInt32ImageType>("out", m_LabelImageSource->GetOutput()); + + // TODO: find an intelligent value of RAM + if (dynamic_cast<OutputImageParameter*>(GetParameterByKey("out"))) + { + OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(GetParameterByKey("out")); + paramDown->SetRAMValue(256); + } + // Get temporary files list m_TemporaryFilesList = controller->GetTemporaryFilesList(); - // Return the label image - return controller->GetLabeledClusteredOutput(); } void DoExecute() { - /* - TODO: the output directory in case the global graph cannot fit in memory (lsgrmController.txx) - */ - // Input image ImageType::Pointer inputImage = GetParameterFloatVectorImage("in"); // Switch criterion int inputCriterion = GetParameterInt("criterion"); if (inputCriterion == CRITERION_BAATZ) { - grm::BaatzParam params; - params.m_SpectralWeight = GetParameterFloat("criterion.bs.cw"); - params.m_ShapeWeight = GetParameterFloat("criterion.bs.sw"); - labelImage = SetGenericParametersAndRunSegmentation<BaatzSegmenterType>(params); + grm::BaatzParam params; + params.m_SpectralWeight = GetParameterFloat("criterion.bs.cw"); + params.m_ShapeWeight = GetParameterFloat("criterion.bs.sw"); + SetGenericParametersAndRunSegmentation<BaatzSegmenterType>(params); } else if (inputCriterion == CRITERION_SPRING) { - grm::SpringParam params; - labelImage = SetGenericParametersAndRunSegmentation<SpringSegmenterType>(params); + grm::SpringParam params; + SetGenericParametersAndRunSegmentation<SpringSegmenterType>(params); } else if (inputCriterion == CRITERION_FLS) { - grm::FLSParam params; - labelImage = SetGenericParametersAndRunSegmentation<FLSSegmenterType>(params); + grm::FLSParam params; + SetGenericParametersAndRunSegmentation<FLSSegmenterType>(params); } else { - otbAppLogFATAL("Unknow criterion!") + otbAppLogFATAL("Unknow criterion!") } - std::cout << "Label image size: " << labelImage->GetLargestPossibleRegion() << std::endl; - - // Set output image projection, origin and spacing for labelImage - labelImage->SetProjectionRef(inputImage->GetProjectionRef()); - labelImage->SetOrigin(inputImage->GetOrigin()); - labelImage->SetSpacing(inputImage->GetSpacing()); - SetParameterOutputImage<UInt32ImageType>("out", labelImage); - } void AfterExecuteAndWriteOutputs() @@ -282,16 +297,16 @@ private: // Delete temporary files for (unsigned int i = 0 ; i < m_TemporaryFilesList.size() ; i++) { - if( remove(m_TemporaryFilesList.at(i).c_str() ) != 0 ) - { - otbAppLogWARNING( "Error deleting file " << m_TemporaryFilesList.at(i) ); - } + if( remove(m_TemporaryFilesList.at(i).c_str() ) != 0 ) + { + otbAppLogWARNING( "Error deleting file " << m_TemporaryFilesList.at(i) ); + } } } private: std::vector<std::string> m_TemporaryFilesList; - UInt32ImageType::Pointer labelImage; + itk::ImageSource<UInt32ImageType>::Pointer m_LabelImageSource; }; // app class } // end of namespace wrapper diff --git a/include/lsgrmController.h b/include/lsgrmController.h index 9550c32..ac8e649 100644 --- a/include/lsgrmController.h +++ b/include/lsgrmController.h @@ -6,6 +6,7 @@ #include "itkObject.h" #include "itkMacro.h" + namespace lsgrm { template<class TSegmenter> @@ -30,6 +31,7 @@ public: using ImageType = typename SegmenterType::ImageType; using LabelImageType = typename SegmenterType::LabelImageType; using SegmentationParameterType = typename SegmenterType::ParamType; + using GraphType = typename SegmenterType::GraphType; /* Default constructor and destructor. */ Controller(); @@ -48,7 +50,6 @@ public: void SetTilingModeUser(){m_TilingMode = LSGRM_TILING_USER; Modified();}; void SetTilingModeAuto(){m_TilingMode = LSGRM_TILING_AUTO; Modified();}; - typename LabelImageType::Pointer GetLabeledClusteredOutput(); std::vector<std::string> GetTemporaryFilesList(); itkGetMacro(Margin, unsigned int); @@ -77,6 +78,8 @@ public: itkGetMacro(TileHeight, unsigned int); itkSetMacro(TileHeight, unsigned int); + itkGetMacro(OutputGraph, GraphType); + private: /** Enum for tiling mode */ @@ -116,7 +119,8 @@ private: LSGRMTilingMode m_TilingMode; // tiling mode (none/user/auto) unsigned int m_Margin; // stability margin related to m_NumberOfFirstIterations std::vector<ProcessingTile> m_Tiles; // list of tiles - typename LabelImageType::Pointer m_LabelImage; // output label image + GraphType m_OutputGraph; // Output graph + }; } // end of namespace lsgrm diff --git a/include/lsgrmController.txx b/include/lsgrmController.txx index 2d2ee41..7f423a2 100644 --- a/include/lsgrmController.txx +++ b/include/lsgrmController.txx @@ -18,6 +18,7 @@ Controller<TSegmenter>::Controller() m_NbTilesY = 0; m_Threshold = 75; m_Memory = 0; + } template<class TSegmenter> @@ -150,7 +151,7 @@ void Controller<TSegmenter>::RunSegmentation() if(accumulatedMemory <= m_Memory) { // Merge all the graphs - m_LabelImage = MergeAllGraphsAndAchieveSegmentation<TSegmenter>( + m_OutputGraph = MergeAllGraphsAndAchieveSegmentation<TSegmenter>( m_SpecificParameters, m_Threshold, m_Tiles, @@ -195,14 +196,15 @@ void Controller<TSegmenter>::RunSegmentation() segmenter.SetInput(m_InputImage); segmenter.Update(); - // Get label image - m_LabelImage = segmenter.GetLabeledClusteredOutput(); + m_OutputGraph = segmenter.m_Graph; } else { itkExceptionMacro(<<"Unknow tiling mode!"); } + // TODO: [MPI] broadcast the graph to other nodes + } /* @@ -433,16 +435,16 @@ void Controller<TSegmenter>::SetSpecificParameters(const SegmentationParameterTy m_SpecificParameters = params; } -template<class TSegmenter> -typename Controller<TSegmenter>::LabelImageType::Pointer -Controller<TSegmenter>::GetLabeledClusteredOutput() -{ -#ifdef OTB_USE_MPI - // Get the label image from the master process (the one which achieves segmentation) - BroadcastImage<typename TSegmenter::LabelImageType>(m_LabelImage); -#endif - return m_LabelImage; -} +//template<class TSegmenter> +//typename Controller<TSegmenter>::LabelImageType::Pointer +//Controller<TSegmenter>::GetLabeledClusteredOutput() +//{ +//#ifdef OTB_USE_MPI +// // Get the label image from the master process (the one which achieves segmentation) +// BroadcastImage<typename TSegmenter::LabelImageType>(m_LabelImage); +//#endif +// return m_LabelImage; +//} template <class TSegmenter> std::vector<std::string> Controller<TSegmenter>::GetTemporaryFilesList() diff --git a/include/lsgrmGraphOperations.h b/include/lsgrmGraphOperations.h index 24d2c2a..28c2111 100644 --- a/include/lsgrmGraphOperations.h +++ b/include/lsgrmGraphOperations.h @@ -5,9 +5,6 @@ #include "grmGraphOperations.h" #include "otbVectorImage.h" #include "otbMultiChannelExtractROI.h" -#include "itkGrayscaleFillholeImageFilter.h" -#include "otbStreamingGraphToImageFilter.h" -#include "otbStreamingImageVirtualWriter.h" namespace lsgrm { @@ -34,7 +31,7 @@ typename TSegmenter::ImageType::Pointer ReadImageRegion( typename TSegmenter::ImageType::RegionType region); template<class TSegmenter> -typename TSegmenter::LabelImageType::Pointer +typename TSegmenter::GraphType MergeAllGraphsAndAchieveSegmentation( const typename TSegmenter::ParamType& params, const float& threshold, diff --git a/include/lsgrmGraphOperations.txx b/include/lsgrmGraphOperations.txx index 15c9b80..6e587ab 100644 --- a/include/lsgrmGraphOperations.txx +++ b/include/lsgrmGraphOperations.txx @@ -25,7 +25,7 @@ typename TSegmenter::ImageType::Pointer ReadImageRegion( } template<class TSegmenter> -typename TSegmenter::LabelImageType::Pointer +typename TSegmenter::GraphType MergeAllGraphsAndAchieveSegmentation( const typename TSegmenter::ParamType& params, const float& threshold, @@ -91,86 +91,30 @@ MergeAllGraphsAndAchieveSegmentation( segmenter.SetThreshold(threshold); segmenter.SetDoFastSegmentation(false); // was true segmenter.SetNumberOfIterations(numberOfIterations); - grm::GraphOperations<TSegmenter>::PerfomAllIterationsWithLMBFAndConstThreshold(segmenter); - // // Write output graph to the output graph directory - // WriteGraph<TSegmenter>(segmenter.m_Graph, tmpDir, 0, 0); - - // TODO: use std::sort to sort the graph (m_Id must be increasing) before the polygon filling - typename TSegmenter::LabelImageType::SizeType outSize; - outSize[0] = imageWidth; - outSize[1] = imageHeight; - typedef StreamingGraphToImageFilter<typename TSegmenter::GraphType, - typename TSegmenter::LabelImageType> GraphToImageFilterType; - typename GraphToImageFilterType::Pointer graphToImageFilter = GraphToImageFilterType::New(); - graphToImageFilter->SetGraph(segmenter.m_Graph); - graphToImageFilter->SetOutputSize(outSize); - typedef otb::ImageFileWriter<typename TSegmenter::LabelImageType> VWriterType; - - typename VWriterType::Pointer wrt = VWriterType::New(); - wrt->SetInput(graphToImageFilter->GetOutput()); - wrt->SetNumberOfDivisionsStrippedStreaming(5); - wrt->SetFileName("/homeL/cresson/data/tmp/spot6_surrech_segm2.tif"); - wrt->Update(); - - // 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); - - using LabelImageIterator = itk::ImageRegionIterator<typename TSegmenter::LabelImageType>; - LabelImageIterator it(labelImage, labelImage->GetLargestPossibleRegion()); - - // 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; - } + // Sort the nodes top-->down and left-->right + std::sort(segmenter.m_Graph.m_Nodes.begin(), segmenter.m_Graph.m_Nodes.end(), + [imageWidth](const auto & a, const auto & b) -> bool + { + lp::CellLists borderPixelsA, borderPixelsB; + lp::ContourOperations::GenerateBorderCells(borderPixelsA, a->m_Contour, a->m_Id, imageWidth); + lp::ContourOperations::GenerateBorderCells(borderPixelsB, b->m_Contour, b->m_Id, imageWidth); - // 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 && inputLabel != noDataLabel) - { - lut[ inputLabel ] = label; - label++; - } - } + unsigned int offA = 0; + unsigned int offB = 0; + for (auto& pix: borderPixelsA) + if (pix>offA) + offA=pix; - // Apply LUT - for(it.GoToBegin();!it.IsAtEnd(); ++it) - it.Set(lut[it.Get()]); + for (auto& pix: borderPixelsB) + if (pix>offB) + offB=pix; - // Fill holes - typedef itk::GrayscaleFillholeImageFilter<typename TSegmenter::LabelImageType, - typename TSegmenter::LabelImageType> FillholeFilterType; - typename FillholeFilterType::Pointer fillFilter = FillholeFilterType::New(); - fillFilter->SetInput(labelImage); - fillFilter->Update(); + return offA > offB; + }); - return fillFilter->GetOutput(); + return segmenter.m_Graph; } template<class TSegmenter> diff --git a/include/otbStreamingGraphToImageFilter.h b/include/otbStreamingGraphToImageFilter.h index d79a92f..1bd3bb4 100644 --- a/include/otbStreamingGraphToImageFilter.h +++ b/include/otbStreamingGraphToImageFilter.h @@ -54,6 +54,8 @@ public: typedef typename TLabelImage::RegionType RegionType; typedef typename TLabelImage::IndexType IndexType; typedef typename TLabelImage::SizeType SizeType; + typedef typename TLabelImage::SpacingType SpacingType; + typedef typename TLabelImage::PointType PointType; typedef typename TGraph::NodePointerType NodePointerType; typedef itk::GrayscaleFillholeImageFilter<TLabelImage,TLabelImage> FillholeFilterType; typedef bg::model::point<float, 2, bg::cs::cartesian> point; @@ -70,9 +72,12 @@ public: virtual void GenerateData(); itkSetMacro(OutputSize, SizeType); + itkSetMacro(OutputOrigin, PointType); + itkSetMacro(OutputSpacing, SpacingType); + itkSetMacro(OutputProjectionRef, std::string); protected: - StreamingGraphToImageFilter(); + StreamingGraphToImageFilter(){}; virtual ~StreamingGraphToImageFilter(){}; private: @@ -80,9 +85,12 @@ private: StreamingGraphToImageFilter(const Self &); //purposely not implemented void operator =(const Self&); //purposely not implemented - TGraph m_Graph; + TGraph m_Graph; bgi::rtree< value, bgi::quadratic<16> > rtree; - SizeType m_OutputSize; + SizeType m_OutputSize; + SpacingType m_OutputSpacing; + PointType m_OutputOrigin; + std::string m_OutputProjectionRef; }; } /* namespace lsgrm */ diff --git a/include/otbStreamingGraphToImageFilter.txx b/include/otbStreamingGraphToImageFilter.txx index 0e984f1..26ef5d0 100644 --- a/include/otbStreamingGraphToImageFilter.txx +++ b/include/otbStreamingGraphToImageFilter.txx @@ -13,13 +13,6 @@ namespace lsgrm { -template <class TGraph, class TLabelImage> -StreamingGraphToImageFilter<TGraph, TLabelImage> -::StreamingGraphToImageFilter() - { - - } - template <class TGraph, class TLabelImage> void StreamingGraphToImageFilter<TGraph, TLabelImage> @@ -28,23 +21,27 @@ StreamingGraphToImageFilter<TGraph, TLabelImage> m_Graph = graph; // Build a R-Tree - std::cout << "Building R-Tree" << std::endl; + itkDebugMacro( << "Building R-Tree" ); + rtree.clear(); unsigned int count = 0; for(auto& node : m_Graph.m_Nodes) { // create a box - box b(point(node->m_Bbox.m_UX, node->m_Bbox.m_UY), - point(node->m_Bbox.m_W, node->m_Bbox.m_UY+node->m_Bbox.m_H)); + box b( + point( + node->m_Bbox.m_UX, + node->m_Bbox.m_UY), + point( + node->m_Bbox.m_UX + node->m_Bbox.m_W, + node->m_Bbox.m_UY + node->m_Bbox.m_H)); // insert new value rtree.insert(std::make_pair(b, count)); count++; } - std::cout << "Building R-Tree finished" << std::endl; - - // TODO: create a LUT for reordering labels from top-->down and left-->right + itkDebugMacro( << "Building R-Tree finished" ); } @@ -53,14 +50,19 @@ void StreamingGraphToImageFilter<TGraph, TLabelImage> ::GenerateOutputInformation() { - TLabelImage * outputPtr = this->GetOutput(); - // TODO: - // outputPtr->SetOrigin ( m_OutputOrigin ); - // outputPtr->SetSpacing ( m_OutputSpacing ); + itkDebugMacro( << "Entering GenerateOutputInformation()" ); + + // Output Largest Possible Region IndexType index; index.Fill(0); RegionType outputRegion(index, m_OutputSize); + + // Set output informations + TLabelImage * outputPtr = this->GetOutput(); + outputPtr->SetOrigin ( m_OutputOrigin ); + outputPtr->SetSpacing ( m_OutputSpacing ); outputPtr->SetLargestPossibleRegion( outputRegion ); + outputPtr->SetProjectionRef(m_OutputProjectionRef); } @@ -70,6 +72,8 @@ void StreamingGraphToImageFilter<TGraph, TLabelImage> ::GenerateData() { + itkDebugMacro( << "Entering GenerateData()" ); + // Allocate the output buffer TLabelImage * outputPtr = this->GetOutput(); RegionType outReqRegion = outputPtr->GetRequestedRegion(); @@ -77,12 +81,17 @@ StreamingGraphToImageFilter<TGraph, TLabelImage> outputPtr->Allocate(); // Find nodes intersecting find the output requested region - box query_box(point(outReqRegion.GetIndex(0), outReqRegion.GetIndex(1)), - point(outReqRegion.GetIndex(0)+outReqRegion.GetSize(0), outReqRegion.GetIndex(1)+outReqRegion.GetSize(1))); + box query_box( + point( + outReqRegion.GetIndex(0), + outReqRegion.GetIndex(1)), + point( + outReqRegion.GetIndex(0)+outReqRegion.GetSize(0), + outReqRegion.GetIndex(1)+outReqRegion.GetSize(1))); std::vector<value> result_s; - std::cout << "R-Tree query on output requested region " << outReqRegion << std::endl; + itkDebugMacro( << "R-Tree query on output requested region " << outReqRegion ); rtree.query(bgi::intersects(query_box), std::back_inserter(result_s)); - std::cout << "R-Tree query done. Number of nodes: " << result_s.size() << std::endl; + itkDebugMacro( << "R-Tree query done. Number of nodes: " << result_s.size() ); // Retrieve the bounding box of the intersecting nodes (a kind of "Input requested region") box realBBox(query_box); @@ -97,23 +106,22 @@ StreamingGraphToImageFilter<TGraph, TLabelImage> size[0] = realBBox.max_corner().get<0>() - realBBox.min_corner().get<0>(); size[1] = realBBox.max_corner().get<1>() - realBBox.min_corner().get<1>(); RegionType inputRequestedRegion(index, size); - std::cout << "Input Requested region: " << inputRequestedRegion << std::endl; + itkDebugMacro( << "Input Requested region: " << inputRequestedRegion ); // Generate the label image - std::cout << "Allocate " << std::endl; + itkDebugMacro( << "Allocate buffered region "); const typename TLabelImage::InternalPixelType noDataLabel = 0; typename TLabelImage::Pointer labelImage = TLabelImage::New(); labelImage->SetRegions(inputRequestedRegion); labelImage->Allocate(); labelImage->FillBuffer(noDataLabel); - std::cout << "Allocate ok" << std::endl; + itkDebugMacro( << "Allocate buffered region ok" ); using LabelImageIterator = itk::ImageRegionIterator<TLabelImage>; LabelImageIterator it(labelImage, inputRequestedRegion); - // Start at 1 (value 0 can be used for invalid pixels) - std::cout << "Iterate " << std::endl; - unsigned int label = 1 ; + // Burn boundaries + itkDebugMacro( << "Burning boundaries " ); for(auto& res : result_s) { NodePointerType node = m_Graph.m_Nodes[res.second]; @@ -125,43 +133,20 @@ StreamingGraphToImageFilter<TGraph, TLabelImage> { index[0] = pix % m_OutputSize[0]; index[1] = pix / m_OutputSize[0]; - labelImage->SetPixel(index, label); - } - ++label; - } - std::cout << "Iterate ok " << std::endl; - - // Re-order nodes labels (left->right to top->bottom) - std::cout << "re-order " << std::endl; - vnl_vector<typename TLabelImage::InternalPixelType> lut(label,noDataLabel); - label = 1; - for(it.GoToBegin();!it.IsAtEnd(); ++it) - { - unsigned int inputLabel = it.Get(); - if (lut[ inputLabel ] == noDataLabel && inputLabel != noDataLabel) - { - lut[ inputLabel ] = label; - label++; + labelImage->SetPixel(index, res.second); } } - std::cout << "re-order ok" << std::endl; - - // Apply LUT - std::cout << "apply LUT" << std::endl; - for(it.GoToBegin();!it.IsAtEnd(); ++it) - it.Set(lut[it.Get()]); - std::cout << "apply LUT ok" << std::endl; + itkDebugMacro( << "Burning boundaries ok "); // Fill holes - std::cout << "fill Hole filter" << std::endl; + itkDebugMacro( << "fill Hole filter" ); typename FillholeFilterType::Pointer fillFilter = FillholeFilterType::New(); fillFilter->SetInput(labelImage); fillFilter->Update(); - std::cout << "Fill Hole filter OutputLargestPossibleRegion:" << fillFilter->GetOutput()->GetLargestPossibleRegion() << std::endl; - std::cout << "fill Hole filter ok" << std::endl; + itkDebugMacro( << "Fill Hole filter OutputLargestPossibleRegion:" << fillFilter->GetOutput()->GetLargestPossibleRegion() ); + itkDebugMacro( << "fill Hole filter ok" ); // Extract the stable region - LabelImageIterator outIt(outputPtr, outReqRegion); LabelImageIterator inIt (fillFilter->GetOutput(), outReqRegion); for (inIt.GoToBegin(), outIt.GoToBegin(); !outIt.IsAtEnd(); ++outIt, ++inIt) -- GitLab