From 35d25a15a11b902c47d87cf51c9bcced92208a15 Mon Sep 17 00:00:00 2001 From: remicres <remi.cresson@teledetection.fr> Date: Wed, 10 Aug 2016 09:50:59 +0000 Subject: [PATCH] FIX: Pierre code + itk::object inheritance implemented --- include/lsgrmController.h | 177 +++++++++++++++++++++++------------- include/lsgrmController.txx | 163 ++++++++++++--------------------- 2 files changed, 171 insertions(+), 169 deletions(-) diff --git a/include/lsgrmController.h b/include/lsgrmController.h index d560f49..ef9dba7 100644 --- a/include/lsgrmController.h +++ b/include/lsgrmController.h @@ -3,74 +3,121 @@ #include "lsrmGetInternalMemory.h" #include "lsgrmSplitter.h" #include "lsgrmGraphOperations.h" +#include "itkObject.h" #include "itkMacro.h" namespace lsgrm -{ - template<class TSegmenter> - class Controller - { - public: - - /* Some convenient typedefs */ - using SegmenterType = TSegmenter; - using ImageType = typename SegmenterType::ImageType; - using LabelImageType = typename SegmenterType::LabelImageType; - using SegmentationParameterType = typename SegmenterType::ParameterType; - - /* Default constructor and destructor. */ - Controller(); - ~Controller(); - - void RunSegmentation(); - - void SetImageDivision(bool f); - void SetInputImage(ImageType * inputImage); - void SetTemporaryDirectory(const std::string& str); - void SetTileWidth(const unsigned int v); - void SetTileHeight(const unsigned int v); - void SetNumberOfFirstIterations(const unsigned int v); - void SetNumberOfIterations(const unsigned int v); - void SetSpecificParameters(const SegmentationParameterType& params); - void SetThreshold(const float& t); - void SetInternalMemoryAvailable(long long unsigned int v); // expecting a value in Mbytes. - void SetAutomaticTilingLayout(bool value); - - typename LabelImageType::Pointer GetLabeledClusteredOutput(); - - itkGetMacro(ListOfTemporaryFiles, std::vector<std::string>); - - private: - - void GetAutomaticConfiguration(); - long unsigned int GetMaximumNumberOfNodesInMemory(); - - /* Parameters given by the user */ - long long unsigned int m_Memory; // RAM available for the computation. - ImageType * m_InputImage; // Input image - std::string m_TemporaryDirectory; // Directory used to store intermediate files during the process. - bool m_ImageDivisionActivated; // The input image must be divided. - bool m_CleanTemporaryDirectory; // Clean the temporary directory. - - /* Specific segmentation parameters */ - SegmentationParameterType m_SpecificParameters; - float m_Threshold; - - /* Internal attribute members.*/ - unsigned int m_NbTilesX; - unsigned int m_NbTilesY; - unsigned int m_NumberOfFirstIterations; - unsigned int m_NumberOfIterations; - unsigned int m_Margin; - unsigned int m_TileWidth; - unsigned int m_TileHeight; - bool m_AutomaticTilingLayout; - - std::vector<ProcessingTile> m_Tiles; - std::vector<std::string> m_ListOfTemporaryFiles; - - typename LabelImageType::Pointer m_LabelImage; - }; +{ +template<class TSegmenter> +class ITK_EXPORT Controller : public itk::Object +{ +public: + + /** Standard class typedef */ + typedef Controller Self; + typedef itk::LightObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Runtime information support. */ + itkTypeMacro(Controller, itk::Object); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Enum for tiling mode */ + enum LSGRMTilingMode + { + LSGRM_TILING_NONE, + LSGRM_TILING_USER, + LSGRM_TILING_AUTO + }; + + /* Some convenient typedefs */ + using SegmenterType = TSegmenter; + using ImageType = typename SegmenterType::ImageType; + using LabelImageType = typename SegmenterType::LabelImageType; + using SegmentationParameterType = typename SegmenterType::ParameterType; + + /* Default constructor and destructor. */ + Controller(); + ~Controller(); + + void RunSegmentation(); + + void SetSpecificParameters(const SegmentationParameterType& params); + void SetInputImage(ImageType * inputImage); + void SetInternalMemoryAvailable(long long unsigned int v); // expecting a value in Mbytes. + + /* Accessors */ + void SetTilingModeNone(){m_TilingMode = LSGRM_TILING_NONE;}; + void SetTilingModeUser(){m_TilingMode = LSGRM_TILING_USER;}; + void SetTilingModeAuto(){m_TilingMode = LSGRM_TILING_AUTO;}; + + typename LabelImageType::Pointer GetLabeledClusteredOutput(); + + itkGetMacro(Margin, unsigned int); + itkGetMacro(TemporaryFilesList, std::vector<std::string>); + + itkGetMacro(CleanTemporaryDirectory, bool); + itkSetMacro(CleanTemporaryDirectory, bool); + + itkGetMacro(TemporaryDirectory, std::string); + itkSetMacro(TemporaryDirectory, std::string); + + itkGetMacro(Threshold, float); + itkSetMacro(Threshold, float); + + itkGetMacro(NumberOfIterations, unsigned int); + itkSetMacro(NumberOfIterations, unsigned int); + + itkGetMacro(NbTilesX, unsigned int); + itkSetMacro(NbTilesX, unsigned int); + + itkGetMacro(NbTilesY, unsigned int); + itkSetMacro(NbTilesY, unsigned int); + + itkGetMacro(NumberOfFirstIterations, unsigned int); + itkSetMacro(NumberOfFirstIterations, unsigned int); + + itkGetMacro(TileWidth, unsigned int); + itkSetMacro(TileWidth, unsigned int); + + itkGetMacro(TileHeight, unsigned int); + itkSetMacro(TileHeight, unsigned int); + +private: + + void GetAutomaticConfiguration(); + long unsigned int GetMaximumNumberOfNodesInMemory(); + + /* Parameters given by the user */ + std::string m_TemporaryDirectory; // Directory used to store intermediate files during the process. + bool m_CleanTemporaryDirectory; // Clean the temporary directory. + ImageType * m_InputImage; // Input image + + /* Segmentation parameters */ + SegmentationParameterType m_SpecificParameters; // Specific parameters + float m_Threshold; // Threshold + unsigned int m_NumberOfIterations; // Number of iterations + + /* Parameters given by the user or computed automatically + * depending of the chosen mode + */ + long long unsigned int m_Memory; // RAM available for the computation. + unsigned int m_NbTilesX; + unsigned int m_NbTilesY; + unsigned int m_NumberOfFirstIterations; + unsigned int m_TileWidth; + unsigned int m_TileHeight; + + /* read-only variables */ + unsigned int m_Margin; + std::vector<ProcessingTile> m_Tiles; + std::vector<std::string> m_TemporaryFilesList; + LSGRMTilingMode m_TilingMode; + typename LabelImageType::Pointer m_LabelImage; +}; } // end of namespace lsgrm #include "lsgrmController.txx" diff --git a/include/lsgrmController.txx b/include/lsgrmController.txx index ba55f0f..a1da11d 100644 --- a/include/lsgrmController.txx +++ b/include/lsgrmController.txx @@ -6,8 +6,7 @@ namespace lsgrm template<class TSegmenter> Controller<TSegmenter>::Controller() { - m_Memory = 0; - m_ImageDivisionActivated = true; + m_TilingMode = LSGRM_TILING_AUTO; } template<class TSegmenter> @@ -19,22 +18,29 @@ template<class TSegmenter> void Controller<TSegmenter>::RunSegmentation() { - // TODO: smarter value? - const unsigned int numberOfIterationsForPartialSegmentations = 3; - unsigned int numberOfIterations = m_NumberOfIterations; - - // Automatic procedure - if(m_Memory == 0) - { - this->GetAutomaticConfiguration(); - } - else + if (m_TilingMode == LSGRM_TILING_AUTO || m_TilingMode == LSGRM_TILING_USER) { - m_Margin = static_cast<unsigned int>(pow(2, m_NumberOfFirstIterations + 1) - 2); - } + // TODO: smarter value? + const unsigned int numberOfIterationsForPartialSegmentations = 3; + unsigned int numberOfIterations = m_NumberOfIterations; + + if(m_TilingMode == LSGRM_TILING_AUTO) + { + this->GetAutomaticConfiguration(); + } + else if (m_TilingMode == LSGRM_TILING_USER) + { + m_Margin = static_cast<unsigned int>(pow(2, m_NumberOfFirstIterations + 1) - 2); + } + + std::cout << + "--- Configuration: \n" << + "\tAvailable RAM: " << m_Memory << "\n" << + "\tInput image dimensions: " << m_InputImage->GetLargestPossibleRegion().GetSize() << "\n" << + "\tNumber of first iterations: " << m_NumberOfFirstIterations << "\n" << + "\tStability margin: " << m_Margin << "\n" << + "\tComputed tile size: " << m_TileWidth << " x " << m_TileHeight << std::endl; - if(m_ImageDivisionActivated) - { // Compute the splitting scheme SplitOTBImage<ImageType>(m_InputImage, m_TileWidth, m_TileHeight, m_Margin, m_NbTilesX, m_NbTilesY, m_Tiles); @@ -115,20 +121,20 @@ void Controller<TSegmenter>::RunSegmentation() m_InputImage->GetNumberOfComponentsPerPixel(), numberOfIterations); - // ShowTime(t); + ShowTime(t); } - else + else // accumulatedMemory > m_Memory { // That means there are no more possible fusions but we can not store the output graph // Todo do not clean up temporary directory before copying resulting graph to the output directory // In the output directory add an info file to give the number of tiles. + itkExceptionMacro(<< "No more possible fusions, but can not store the output graph"); } - } - else + else // tiling_mode is none { - //TODO: use classic GRM + // todo use classic grm } @@ -158,6 +164,12 @@ long unsigned int Controller<TSegmenter>::GetMaximumNumberOfNodesInMemory() } +/* + * Compute a tiling layout such as tiles respect following constraints, + * sorted by priority: + * 1.number of nodes in a regular tile should fit the available memory + * 2.regular tiles compactness must be the smallest + */ template<class TSegmenter> void Controller<TSegmenter>::GetAutomaticConfiguration() { @@ -169,7 +181,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() // (assuming that maxMargin = tileDimension/2) maximumNumberOfNodesInMemory /= 4; - // Find the largest tile with the lowest compactness + // Find the largest tile size const unsigned int imageWidth = m_InputImage->GetLargestPossibleRegion().GetSize()[0]; const unsigned int imageHeight = m_InputImage->GetLargestPossibleRegion().GetSize()[1]; unsigned int nbOfTiles = 1; // total number of tiles @@ -179,32 +191,34 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() unsigned int tileWidth(0), tileHeight(0); while( nbOfNodesInImage / ((float) nbOfTiles) > maximumNumberOfNodesInMemory) { - // Get the multiples of k. For each one, compute the - // layout which has the minimum tile compactness - float lowestCompactness = itk::NumericTraits<float>::max(); - for (unsigned int layoutNCol = 1; layoutNCol<=nbOfTiles; layoutNCol++) + nbOfTiles++; + } + nbOfTiles--; + + // Get the multiples of k. For each one, compute the + // layout which has the minimum tile compactness + float lowestCompactness = itk::NumericTraits<float>::max(); + for (unsigned int layoutNCol = 1; layoutNCol<=nbOfTiles; layoutNCol++) + { + if (nbOfTiles % layoutNCol == 0) // Is it a multiple of the nb of Tiles? { - if (nbOfTiles % layoutNCol == 0) // Is it a multiple of the nb of Tiles? + // Compute tile compactness + unsigned int layoutNRow = nbOfTiles / layoutNCol; + tileWidth = imageWidth / layoutNCol; + tileHeight = imageHeight / layoutNRow; + float perimeter = tileWidth + tileHeight; + float surface = tileWidth * tileHeight; + float compactness = perimeter / surface; + + // Update minimum compactness + if (lowestCompactness > compactness) { - // Compute tile compactness - unsigned int layoutNRow = nbOfTiles / layoutNCol; - tileWidth = imageWidth / layoutNCol; - tileHeight = imageHeight / layoutNRow; - float perimeter = tileWidth + tileHeight; - float surface = tileWidth * tileHeight; - float compactness = perimeter / surface; - - // Update minimum compactness - if (lowestCompactness > compactness) - { - lowestCompactness = compactness; - m_NbTilesX = layoutNCol; - m_NbTilesY = layoutNRow; - } + lowestCompactness = compactness; + m_NbTilesX = layoutNCol; + m_NbTilesY = layoutNRow; } - } // for each multiple of k - nbOfTiles++; - } // while + } + } // for each multiple of k // Compute the tile size m_TileWidth = static_cast<unsigned int>(imageWidth/m_NbTilesX); @@ -227,22 +241,6 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() m_Margin = prevMargin; m_NumberOfFirstIterations = niter - 1; - std::cout << - "--- Configuration: \n" << - "\tAvailable RAM: " << m_Memory << "\n" << - "\tInput image dimensions: " << imageWidth << " x " << imageHeight << "\n" << - "\tMaximum number of nodes in memory: " << maximumNumberOfNodesInMemory << "\n" << - "\tOptimal square tile size: " << tileDimension << "\n" << - "\tNumber of first iterations: " << niter << "\n" << - "\tStability margin: " << prevMargin << "\n" << - "\tComputed tile size: " << m_TileWidth << " x " << m_TileHeight << std::endl; - -} - -template <class TSegmenter> -void Controller<TSegmenter>::SetTemporaryDirectory(const std::string& str) -{ - m_TemporaryDirectory = str; } template <class TSegmenter> @@ -252,61 +250,18 @@ void Controller<TSegmenter>::SetInternalMemoryAvailable(long long unsigned int v m_Memory = v * 1024ul * 1024ul; } -template<class TSegmenter> -void Controller<TSegmenter>::SetImageDivision(bool f) -{ - m_ImageDivisionActivated = f; -} - -template<class TSegmenter> -void Controller<TSegmenter>::SetAutomaticTilingLayout(bool value) -{ - m_AutomaticTilingLayout = value; -} - template<class TSegmenter> void Controller<TSegmenter>::SetInputImage(ImageType * inputImage) { m_InputImage = inputImage; } -template<class TSegmenter> -void Controller<TSegmenter>::SetTileWidth(const unsigned int v) -{ - m_TileWidth = v; -} - -template<class TSegmenter> -void Controller<TSegmenter>::SetTileHeight(const unsigned int v) -{ - m_TileHeight = v; -} - -template<class TSegmenter> -void Controller<TSegmenter>::SetNumberOfFirstIterations(const unsigned int v) -{ - m_NumberOfFirstIterations = v; - m_Margin = static_cast<unsigned int>(pow(2, m_NumberOfFirstIterations + 1) - 2);// 2^{n+1}-2 -} - -template<class TSegmenter> -void Controller<TSegmenter>::SetNumberOfIterations(const unsigned int v) -{ - m_NumberOfIterations = v; -} - template<class TSegmenter> void Controller<TSegmenter>::SetSpecificParameters(const SegmentationParameterType& params) { m_SpecificParameters = params; } -template<class TSegmenter> -void Controller<TSegmenter>::SetThreshold(const float& t) -{ - m_Threshold = t; -} - template<class TSegmenter> typename Controller<TSegmenter>::LabelImageType::Pointer Controller<TSegmenter>::GetLabeledClusteredOutput() -- GitLab