diff --git a/include/lsgrmController.h b/include/lsgrmController.h index 933c0a42d4971bd88f88c688822b1945686f933e..afaba38389be0be222023eb92da2b992f1367f44 100644 --- a/include/lsgrmController.h +++ b/include/lsgrmController.h @@ -90,6 +90,7 @@ private: void GetAutomaticConfiguration(); void ComputeMaximumStabilityMargin(unsigned int width, unsigned int height, unsigned int &iter, unsigned int &margin); + unsigned int GetNodeMemory(); long unsigned int GetMaximumNumberOfNodesInMemory(); /* Parameters given by the user */ diff --git a/include/lsgrmController.txx b/include/lsgrmController.txx index 79e77591c9e052f34bb744ad016e2527dde4c2f5..9baafe8aa441080a5af88baff2af26341977cae2 100644 --- a/include/lsgrmController.txx +++ b/include/lsgrmController.txx @@ -154,7 +154,32 @@ void Controller<TSegmenter>::RunSegmentation() } +/* + * Compute the memory occupied by one node + */ +template<class TSegmenter> +unsigned int Controller<TSegmenter>::GetNodeMemory() +{ + // Create a unique node + typename ImageType::Pointer onePixelImage = ImageType::New(); + typename ImageType::IndexType start; + start.Fill(0); + typename ImageType::SizeType size; + size.Fill(1); + typename ImageType::RegionType region(start, size); + onePixelImage->SetRegions(region); + onePixelImage->SetNumberOfComponentsPerPixel(m_InputImage->GetNumberOfComponentsPerPixel()); + onePixelImage->Allocate(); + TSegmenter segmenter; + segmenter.SetInput(onePixelImage); + lsrm::GraphOperations<TSegmenter>::InitNodes(onePixelImage,segmenter,FOUR); + + return segmenter.GetGraphMemory(); +} +/* + * Compute the maximum number of nodes which can fit in the system memory + */ template<class TSegmenter> long unsigned int Controller<TSegmenter>::GetMaximumNumberOfNodesInMemory() { @@ -165,42 +190,39 @@ long unsigned int Controller<TSegmenter>::GetMaximumNumberOfNodesInMemory() m_Memory /= 2; // For safety and can prevent out of memory troubles - TSegmenter segmenter; - segmenter.SetInput(m_InputImage); - - unsigned int nodeMemory = segmenter.GetNodeMemory(4); // 4 neighborhood - return std::ceil(((float) m_Memory) / ((float) nodeMemory)); + return std::ceil(((float) m_Memory) / ((float) GetNodeMemory())); } template<class TSegmenter> void Controller<TSegmenter>::ComputeMaximumStabilityMargin(unsigned int width, unsigned int height, unsigned int &niter, unsigned int &margin) -{ + { itkDebugMacro(<< "Computing maximum stability margin"); // Compute the stability margin. The naive strategy consider a margin value and a stable size equal. - unsigned int tileDimension = std::min(width, height); niter = 1; - unsigned int maxMargin = tileDimension/2; - margin = static_cast<unsigned int>(pow(2, niter + 1) - 2); - unsigned int prevMargin = margin; + unsigned int maxMargin = std::min(width, height)/2; + unsigned int currMargin = static_cast<unsigned int>(pow(2, niter + 1) - 2); + margin = currMargin; - while(margin < maxMargin) + while(currMargin < maxMargin) { - prevMargin = margin; + margin = currMargin; niter++; - margin = static_cast<unsigned int>(pow(2, niter + 1) - 2); + currMargin = static_cast<unsigned int>(pow(2, niter + 1) - 2); } niter--; itkDebugMacro(<< "Number of iterations=" << niter << " margin=" << margin); -} + } /* - * Compute a tiling layout which minimizes a criterion based on tile compacity + * Compute a tiling layout which minimizes a criterion based on tile compactness * and memory usage + * + * TODO: use the lsgrmSplitter to truly compute the largest tile of a given layout */ template<class TSegmenter> void Controller<TSegmenter>::GetAutomaticConfiguration() @@ -217,8 +239,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() const unsigned int imageHeight = m_InputImage->GetLargestPossibleRegion().GetSize()[1]; const unsigned long int nbOfNodesInImage = imageWidth*imageHeight; - // Initialize layout with 1x1 - unsigned int nbOfTiles = 1; // Number of tiles in the layout + // Default layout: 1x1 m_NbTilesX = 1; m_NbTilesY = 1; @@ -306,7 +327,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() TSegmenter segmenter; segmenter.SetInput(m_InputImage); - unsigned int nodeMemory = segmenter.GetNodeMemory(4); // 4 neighborhood + unsigned int nodeMemory = GetNodeMemory(); unsigned int memoryUsed = (m_TileHeight + 2*m_Margin)*(m_TileWidth + 2*m_Margin)*nodeMemory; itkWarningMacro(<< "An amount of " << (memoryUsed / (1024.0*1024.0)) << " Mbytes of RAM will be used for regular tiles of size " << (m_TileWidth + 2*m_Margin) << "x" << (m_TileHeight + 2*m_Margin) ); diff --git a/include/lsrmBaatzSegmenter.h b/include/lsrmBaatzSegmenter.h index 53dbf7e207688b00a41e0d25095cb2b5f85d5781..76fef41248cf0e34fc059c8a4631a148f1d0097f 100644 --- a/include/lsrmBaatzSegmenter.h +++ b/include/lsrmBaatzSegmenter.h @@ -94,7 +94,7 @@ namespace lsrm float ComputeMergingCost(NodePointerType n1, NodePointerType n2); void UpdateSpecificAttributes(NodePointerType n1, NodePointerType n2); void InitFromImage(); - unsigned int GetNodeMemory(unsigned int nEdges); + unsigned int GetNodeMemory(NodePointerType &node); }; } // end of namespace lsrm diff --git a/include/lsrmBaatzSegmenter.txx b/include/lsrmBaatzSegmenter.txx index 362c64bb1f78dee0205e298da7b2a3fa172204c6..0c36fa6649032f45ba1811bd7533d89b5432fdd6 100644 --- a/include/lsrmBaatzSegmenter.txx +++ b/include/lsrmBaatzSegmenter.txx @@ -132,16 +132,16 @@ namespace lsrm template<class TImage> unsigned int - BaatzSegmenter<TImage>::GetNodeMemory(unsigned int nEdges) + BaatzSegmenter<TImage>::GetNodeMemory(NodePointerType &node) { unsigned int nBands = this->m_InputImage->GetNumberOfComponentsPerPixel(); long long unsigned int memory = 0; memory += sizeof(NodePointerType); // size of the node pointer - memory += sizeof(NodeType); // size of the node + memory += sizeof(NodeType); // size of the node (actually, size of the base node) memory += 4 * nBands * sizeof(float); // size of the 4 attributes, multiplied by the nb. of bands - memory += nEdges * sizeof(EdgeType); // size of the edges + memory += node->m_Edges.size() * sizeof(EdgeType); // size of the edges return memory; } } // end of namespace lsrm diff --git a/include/lsrmSegmenter.h b/include/lsrmSegmenter.h index bedc01a8cb63b11c43b43fd2f4921bbf123d2d6f..516afc76e69e3896c4142c0aaa1fd4a95331d270 100644 --- a/include/lsrmSegmenter.h +++ b/include/lsrmSegmenter.h @@ -84,7 +84,7 @@ namespace lsrm /* * Returns the memory (in bytes) occupied by one node of the graph */ - virtual unsigned int GetNodeMemory(unsigned int nEdges) = 0; + virtual unsigned int GetNodeMemory(NodePointerType &node) = 0; /* * Returns the memory (in bytes) occupied by the entire graph @@ -96,7 +96,7 @@ namespace lsrm for(auto& node : m_Graph.m_Nodes) { numberOfMoves += node->m_Contour.size(); - memory += this->GetNodeMemory(node->m_Edges.size()); + memory += this->GetNodeMemory(node); } memory += std::ceil(numberOfMoves / 4);