Commit 35d25a15 authored by remicres's avatar remicres
Browse files

FIX: Pierre code + itk::object inheritance implemented

Showing with 171 additions and 169 deletions
+171 -169
...@@ -3,74 +3,121 @@ ...@@ -3,74 +3,121 @@
#include "lsrmGetInternalMemory.h" #include "lsrmGetInternalMemory.h"
#include "lsgrmSplitter.h" #include "lsgrmSplitter.h"
#include "lsgrmGraphOperations.h" #include "lsgrmGraphOperations.h"
#include "itkObject.h"
#include "itkMacro.h" #include "itkMacro.h"
namespace lsgrm namespace lsgrm
{ {
template<class TSegmenter> template<class TSegmenter>
class Controller class ITK_EXPORT Controller : public itk::Object
{ {
public: public:
/* Some convenient typedefs */ /** Standard class typedef */
using SegmenterType = TSegmenter; typedef Controller Self;
using ImageType = typename SegmenterType::ImageType; typedef itk::LightObject Superclass;
using LabelImageType = typename SegmenterType::LabelImageType; typedef itk::SmartPointer<Self> Pointer;
using SegmentationParameterType = typename SegmenterType::ParameterType; typedef itk::SmartPointer<const Self> ConstPointer;
/* Default constructor and destructor. */ /** Runtime information support. */
Controller(); itkTypeMacro(Controller, itk::Object);
~Controller();
/** Method for creation through the object factory. */
void RunSegmentation(); itkNewMacro(Self);
void SetImageDivision(bool f); /** Enum for tiling mode */
void SetInputImage(ImageType * inputImage); enum LSGRMTilingMode
void SetTemporaryDirectory(const std::string& str); {
void SetTileWidth(const unsigned int v); LSGRM_TILING_NONE,
void SetTileHeight(const unsigned int v); LSGRM_TILING_USER,
void SetNumberOfFirstIterations(const unsigned int v); LSGRM_TILING_AUTO
void SetNumberOfIterations(const unsigned int v); };
void SetSpecificParameters(const SegmentationParameterType& params);
void SetThreshold(const float& t); /* Some convenient typedefs */
void SetInternalMemoryAvailable(long long unsigned int v); // expecting a value in Mbytes. using SegmenterType = TSegmenter;
void SetAutomaticTilingLayout(bool value); using ImageType = typename SegmenterType::ImageType;
using LabelImageType = typename SegmenterType::LabelImageType;
typename LabelImageType::Pointer GetLabeledClusteredOutput(); using SegmentationParameterType = typename SegmenterType::ParameterType;
itkGetMacro(ListOfTemporaryFiles, std::vector<std::string>); /* Default constructor and destructor. */
Controller();
private: ~Controller();
void GetAutomaticConfiguration(); void RunSegmentation();
long unsigned int GetMaximumNumberOfNodesInMemory();
void SetSpecificParameters(const SegmentationParameterType& params);
/* Parameters given by the user */ void SetInputImage(ImageType * inputImage);
long long unsigned int m_Memory; // RAM available for the computation. void SetInternalMemoryAvailable(long long unsigned int v); // expecting a value in Mbytes.
ImageType * m_InputImage; // Input image
std::string m_TemporaryDirectory; // Directory used to store intermediate files during the process. /* Accessors */
bool m_ImageDivisionActivated; // The input image must be divided. void SetTilingModeNone(){m_TilingMode = LSGRM_TILING_NONE;};
bool m_CleanTemporaryDirectory; // Clean the temporary directory. void SetTilingModeUser(){m_TilingMode = LSGRM_TILING_USER;};
void SetTilingModeAuto(){m_TilingMode = LSGRM_TILING_AUTO;};
/* Specific segmentation parameters */
SegmentationParameterType m_SpecificParameters; typename LabelImageType::Pointer GetLabeledClusteredOutput();
float m_Threshold;
itkGetMacro(Margin, unsigned int);
/* Internal attribute members.*/ itkGetMacro(TemporaryFilesList, std::vector<std::string>);
unsigned int m_NbTilesX;
unsigned int m_NbTilesY; itkGetMacro(CleanTemporaryDirectory, bool);
unsigned int m_NumberOfFirstIterations; itkSetMacro(CleanTemporaryDirectory, bool);
unsigned int m_NumberOfIterations;
unsigned int m_Margin; itkGetMacro(TemporaryDirectory, std::string);
unsigned int m_TileWidth; itkSetMacro(TemporaryDirectory, std::string);
unsigned int m_TileHeight;
bool m_AutomaticTilingLayout; itkGetMacro(Threshold, float);
itkSetMacro(Threshold, float);
std::vector<ProcessingTile> m_Tiles;
std::vector<std::string> m_ListOfTemporaryFiles; itkGetMacro(NumberOfIterations, unsigned int);
itkSetMacro(NumberOfIterations, unsigned int);
typename LabelImageType::Pointer m_LabelImage;
}; 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 } // end of namespace lsgrm
#include "lsgrmController.txx" #include "lsgrmController.txx"
......
...@@ -6,8 +6,7 @@ namespace lsgrm ...@@ -6,8 +6,7 @@ namespace lsgrm
template<class TSegmenter> template<class TSegmenter>
Controller<TSegmenter>::Controller() Controller<TSegmenter>::Controller()
{ {
m_Memory = 0; m_TilingMode = LSGRM_TILING_AUTO;
m_ImageDivisionActivated = true;
} }
template<class TSegmenter> template<class TSegmenter>
...@@ -19,22 +18,29 @@ template<class TSegmenter> ...@@ -19,22 +18,29 @@ template<class TSegmenter>
void Controller<TSegmenter>::RunSegmentation() void Controller<TSegmenter>::RunSegmentation()
{ {
// TODO: smarter value? if (m_TilingMode == LSGRM_TILING_AUTO || m_TilingMode == LSGRM_TILING_USER)
const unsigned int numberOfIterationsForPartialSegmentations = 3;
unsigned int numberOfIterations = m_NumberOfIterations;
// Automatic procedure
if(m_Memory == 0)
{
this->GetAutomaticConfiguration();
}
else
{ {
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 // Compute the splitting scheme
SplitOTBImage<ImageType>(m_InputImage, m_TileWidth, m_TileHeight, m_Margin, SplitOTBImage<ImageType>(m_InputImage, m_TileWidth, m_TileHeight, m_Margin,
m_NbTilesX, m_NbTilesY, m_Tiles); m_NbTilesX, m_NbTilesY, m_Tiles);
...@@ -115,20 +121,20 @@ void Controller<TSegmenter>::RunSegmentation() ...@@ -115,20 +121,20 @@ void Controller<TSegmenter>::RunSegmentation()
m_InputImage->GetNumberOfComponentsPerPixel(), m_InputImage->GetNumberOfComponentsPerPixel(),
numberOfIterations); 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 // 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 // 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. // 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() ...@@ -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> template<class TSegmenter>
void Controller<TSegmenter>::GetAutomaticConfiguration() void Controller<TSegmenter>::GetAutomaticConfiguration()
{ {
...@@ -169,7 +181,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() ...@@ -169,7 +181,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration()
// (assuming that maxMargin = tileDimension/2) // (assuming that maxMargin = tileDimension/2)
maximumNumberOfNodesInMemory /= 4; 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 imageWidth = m_InputImage->GetLargestPossibleRegion().GetSize()[0];
const unsigned int imageHeight = m_InputImage->GetLargestPossibleRegion().GetSize()[1]; const unsigned int imageHeight = m_InputImage->GetLargestPossibleRegion().GetSize()[1];
unsigned int nbOfTiles = 1; // total number of tiles unsigned int nbOfTiles = 1; // total number of tiles
...@@ -179,32 +191,34 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() ...@@ -179,32 +191,34 @@ void Controller<TSegmenter>::GetAutomaticConfiguration()
unsigned int tileWidth(0), tileHeight(0); unsigned int tileWidth(0), tileHeight(0);
while( nbOfNodesInImage / ((float) nbOfTiles) > maximumNumberOfNodesInMemory) while( nbOfNodesInImage / ((float) nbOfTiles) > maximumNumberOfNodesInMemory)
{ {
// Get the multiples of k. For each one, compute the nbOfTiles++;
// layout which has the minimum tile compactness }
float lowestCompactness = itk::NumericTraits<float>::max(); nbOfTiles--;
for (unsigned int layoutNCol = 1; layoutNCol<=nbOfTiles; layoutNCol++)
// 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 lowestCompactness = compactness;
unsigned int layoutNRow = nbOfTiles / layoutNCol; m_NbTilesX = layoutNCol;
tileWidth = imageWidth / layoutNCol; m_NbTilesY = layoutNRow;
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;
}
} }
} // for each multiple of k }
nbOfTiles++; } // for each multiple of k
} // while
// Compute the tile size // Compute the tile size
m_TileWidth = static_cast<unsigned int>(imageWidth/m_NbTilesX); m_TileWidth = static_cast<unsigned int>(imageWidth/m_NbTilesX);
...@@ -227,22 +241,6 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() ...@@ -227,22 +241,6 @@ void Controller<TSegmenter>::GetAutomaticConfiguration()
m_Margin = prevMargin; m_Margin = prevMargin;
m_NumberOfFirstIterations = niter - 1; 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> template <class TSegmenter>
...@@ -252,61 +250,18 @@ void Controller<TSegmenter>::SetInternalMemoryAvailable(long long unsigned int v ...@@ -252,61 +250,18 @@ void Controller<TSegmenter>::SetInternalMemoryAvailable(long long unsigned int v
m_Memory = v * 1024ul * 1024ul; 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> template<class TSegmenter>
void Controller<TSegmenter>::SetInputImage(ImageType * inputImage) void Controller<TSegmenter>::SetInputImage(ImageType * inputImage)
{ {
m_InputImage = 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> template<class TSegmenter>
void Controller<TSegmenter>::SetSpecificParameters(const SegmentationParameterType& params) void Controller<TSegmenter>::SetSpecificParameters(const SegmentationParameterType& params)
{ {
m_SpecificParameters = params; m_SpecificParameters = params;
} }
template<class TSegmenter>
void Controller<TSegmenter>::SetThreshold(const float& t)
{
m_Threshold = t;
}
template<class TSegmenter> template<class TSegmenter>
typename Controller<TSegmenter>::LabelImageType::Pointer typename Controller<TSegmenter>::LabelImageType::Pointer
Controller<TSegmenter>::GetLabeledClusteredOutput() Controller<TSegmenter>::GetLabeledClusteredOutput()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment