Commit 4f606e07 authored by remi cresson's avatar remi cresson

ENH: implement Raffaele Gaetano's patch and refactorization

parent 5367de74
...@@ -28,114 +28,51 @@ namespace grm ...@@ -28,114 +28,51 @@ namespace grm
SegmenterType& seg, SegmenterType& seg,
CONNECTIVITY mask) CONNECTIVITY mask)
{ {
unsigned int width, height;
{
width = inputImg->GetLargestPossibleRegion().GetSize()[0];
height = inputImg->GetLargestPossibleRegion().GetSize()[1];
}
const long unsigned int num_nodes = width * height;
seg.m_Graph.m_Nodes.reserve(num_nodes);
std::vector<bool> noDataFlags;
std::vector<double> noDataValues;
bool noDataPresent = otb::ReadNoDataFlags(inputImg->GetMetaDataDictionary(), noDataFlags, noDataValues);
typedef itk::ImageRegionIterator<ImageType> ImageIterator;
ImageIterator it(inputImg, inputImg->GetLargestPossibleRegion());
unsigned int i = 0;
for(it.GoToBegin(); !it.IsAtEnd(); ++it) {
NodePointerType n(new NodeType);
n->m_Id = i;
n->m_Valid = true;
n->m_Expired = (noDataPresent && otb::IsNoData<double>(it.Get(), noDataFlags, noDataValues));
n->m_IsMerged = true; // force to compute costs for the first iteration
n->m_Perimeter = 4;
n->m_Area = 1;
n->m_Bbox.m_UX = i % width;
n->m_Bbox.m_UY = i / width;
n->m_Bbox.m_W = 1;
n->m_Bbox.m_H = 1;
// An initial contour is the one aroun a pixel
ContourOperator::Push1(n->m_Contour);
ContourOperator::Push2(n->m_Contour);
ContourOperator::Push3(n->m_Contour);
ContourOperator::Push0(n->m_Contour);
seg.m_Graph.m_Nodes.push_back(n);
++i;
}
/* // Initialize nodes
for(long unsigned int i = 0; seg.InitFromImage();
i < num_nodes;
++i) // Compute the neighborhood for each node
{ const unsigned int width = inputImg->GetLargestPossibleRegion().GetSize()[0];
NodePointerType n(new NodeType); const unsigned int height = inputImg->GetLargestPossibleRegion().GetSize()[1];
n->m_Id = i; if(mask == FOUR)
n->m_Valid = true; {
n->m_Expired = false; for(auto& r : seg.m_Graph.m_Nodes)
n->m_IsMerged = true; // force to compute costs for the first iteration {
n->m_Perimeter = 4; long int neighborhood[4];
n->m_Area = 1; FOURNeighborhood(neighborhood, r->m_Id, width, height);
n->m_Bbox.m_UX = i % width; for(short j = 0; j < 4; ++j)
n->m_Bbox.m_UY = i / width; {
n->m_Bbox.m_W = 1; if(neighborhood[j] > -1 && !seg.m_Graph.m_Nodes[neighborhood[j]]->m_Expired)
n->m_Bbox.m_H = 1; r->m_Edges.push_back(EdgeType( seg.m_Graph.m_Nodes[neighborhood[j]], 0, 1));
}
// An initial contour is the one aroun a pixel r->m_Valid = (r->m_Edges.size() > 0);
ContourOperator::Push1(n->m_Contour); }
ContourOperator::Push2(n->m_Contour); }
ContourOperator::Push3(n->m_Contour); else
ContourOperator::Push0(n->m_Contour); {
for(auto& r : seg.m_Graph.m_Nodes)
seg.m_Graph.m_Nodes.push_back(n); {
} long int neighborhood[8];
*/ EIGHTNeighborhood(neighborhood, r->m_Id, width, height);
bool haveNeighbors = false;
for(short j = 0; j < 8; ++j)
{
if(neighborhood[j] > -1 && !seg.m_Graph.m_Nodes[neighborhood[j]]->m_Expired)
{
if(j % 2 > 0)
r->m_Edges.push_back(EdgeType( seg.m_Graph.m_Nodes[neighborhood[j]], 0, 0));
else
r->m_Edges.push_back(EdgeType( seg.m_Graph.m_Nodes[neighborhood[j]], 0, 1));
}
}
r->m_Valid = (r->m_Edges.size() > 0);
}
}
// Remove no-data nodes
RemoveExpiredNodes(seg.m_Graph);
if(mask == FOUR)
{
for(auto& r : seg.m_Graph.m_Nodes)
{
long int neighborhood[4];
FOURNeighborhood(neighborhood, r->m_Id, width, height);
for(short j = 0; j < 4; ++j)
{
if(neighborhood[j] > -1 && !seg.m_Graph.m_Nodes[neighborhood[j]]->m_Expired)
r->m_Edges.push_back(EdgeType( seg.m_Graph.m_Nodes[neighborhood[j]], 0, 1));
}
r->m_Valid = (r->m_Edges.size() > 0);
}
}
else
{
for(auto& r : seg.m_Graph.m_Nodes)
{
long int neighborhood[8];
EIGHTNeighborhood(neighborhood, r->m_Id, width, height);
bool haveNeighbors = false;
for(short j = 0; j < 8; ++j)
{
if(neighborhood[j] > -1 && !seg.m_Graph.m_Nodes[neighborhood[j]]->m_Expired)
{
if(j % 2 > 0)
r->m_Edges.push_back(EdgeType( seg.m_Graph.m_Nodes[neighborhood[j]], 0, 0));
else
r->m_Edges.push_back(EdgeType( seg.m_Graph.m_Nodes[neighborhood[j]], 0, 1));
}
}
r->m_Valid = (r->m_Edges.size() > 0);
}
}
seg.InitFromImage();
RemoveExpiredNodes(seg.m_Graph);
} }
template<class TSegmenter> template<class TSegmenter>
...@@ -592,4 +529,4 @@ namespace grm ...@@ -592,4 +529,4 @@ namespace grm
} }
} // end of namespace grm } // end of namespace grm
#endif #endif
\ No newline at end of file
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#include "grmMacroGenerator.h" #include "grmMacroGenerator.h"
#include "grmGraphOperations.h" #include "grmGraphOperations.h"
#include "grmGraphToOtbImage.h" #include "grmGraphToOtbImage.h"
#include "grmNeighborhood.h"
#include "grmGraphOperations.h"
#include <otbImageFileReader.h> #include <otbImageFileReader.h>
#include <itkImageRegionIterator.h> #include <itkImageRegionIterator.h>
#include "otbNoDataHelper.h" #include "otbNoDataHelper.h"
...@@ -126,6 +129,9 @@ namespace grm ...@@ -126,6 +129,9 @@ namespace grm
this->m_ImageHeight =this->m_InputImage->GetLargestPossibleRegion().GetSize()[1]; this->m_ImageHeight =this->m_InputImage->GetLargestPossibleRegion().GetSize()[1];
this->m_NumberOfComponentsPerPixel = this->m_InputImage->GetNumberOfComponentsPerPixel(); this->m_NumberOfComponentsPerPixel = this->m_InputImage->GetNumberOfComponentsPerPixel();
const long unsigned int num_nodes = this->m_ImageWidth * this->m_ImageHeight;
this->m_Graph.m_Nodes.reserve(num_nodes);
std::vector<bool> noDataFlags; std::vector<bool> noDataFlags;
std::vector<double> noDataValues; std::vector<double> noDataValues;
bool noDataPresent = otb::ReadNoDataFlags(this->m_InputImage->GetMetaDataDictionary(),noDataFlags,noDataValues); bool noDataPresent = otb::ReadNoDataFlags(this->m_InputImage->GetMetaDataDictionary(),noDataFlags,noDataValues);
...@@ -134,16 +140,30 @@ namespace grm ...@@ -134,16 +140,30 @@ namespace grm
ImageIterator it(this->m_InputImage, this->m_InputImage->GetLargestPossibleRegion()); ImageIterator it(this->m_InputImage, this->m_InputImage->GetLargestPossibleRegion());
for(it.GoToBegin(); !it.IsAtEnd(); ++it) for(it.GoToBegin(); !it.IsAtEnd(); ++it)
{ {
NodePointerType n(new NodeType);
if (noDataPresent && otb::IsNoData<double>(it.Get(),noDataFlags,noDataValues)) n->m_Id = idx;
{ n->m_Valid = true;
this->m_Graph.m_Nodes[idx]->m_Expired = true; n->m_Expired = (noDataPresent && otb::IsNoData<double>(it.Get(),noDataFlags,noDataValues));
} n->m_IsMerged = true; // force to compute costs for the first iteration
else n->m_Perimeter = 4;
{ n->m_Area = 1;
UpdateSpecificAttributes(this->m_Graph.m_Nodes[idx], it.Get()); n->m_Bbox.m_UX = it.GetIndex()[0];
} n->m_Bbox.m_UY = it.GetIndex()[1];
n->m_Bbox.m_W = 1;
n->m_Bbox.m_H = 1;
// An initial contour is the one aroun a pixel
lp::ContourOperations::Push1(n->m_Contour);
lp::ContourOperations::Push2(n->m_Contour);
lp::ContourOperations::Push3(n->m_Contour);
lp::ContourOperations::Push0(n->m_Contour);
// Update attributes
UpdateSpecificAttributes(n, it.Get());
this->m_Graph.m_Nodes.push_back(n);
++idx; ++idx;
} }
} }
......
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