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

FIX: Pierre code + itk::object inheritance implemented

parent cf9a43e2
......@@ -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"
......
......@@ -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()
......
Markdown is supported
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