In many circumstances, it is better to use the presented graph structure of digital surfaces. For instance it may be used to find the surface just by searching it by adjacencies. This process is called tracking. This is done for you by static method Surfaces::trackBoundary.
#include <iostream>
#include <queue>
#include "DGtal/base/Common.h"
#include "DGtal/io/viewers/Viewer3D.h"
#include "DGtal/io/readers/VolReader.h"
#include "DGtal/io/DrawWithDisplay3DModifier.h"
#include "DGtal/io/Color.h"
#include "DGtal/images/ImageSelector.h"
#include "DGtal/images/imagesSetsUtils/SetFromImage.h"
#include "DGtal/shapes/Shapes.h"
#include "DGtal/helpers/StdDefs.h"
#include "DGtal/topology/helpers/Surfaces.h"
using namespace std;
using namespace Z3i;
void usage(
int ,
char** argv )
{
std::cerr << "Usage: " << argv[ 0 ] << " <fileName.vol> <minT> <maxT>" << std::endl;
std::cerr << "\t - displays the boundary of the shape stored in vol file <fileName.vol>." << std::endl;
std::cerr << "\t - voxel v belongs to the shape iff its value I(v) follows minT <= I(v) <= maxT." << std::endl;
}
int main(
int argc,
char** argv )
{
if ( argc < 4 )
{
return 1;
}
std::string inputFilename = argv[ 1 ];
unsigned int minThreshold = atoi( argv[ 2 ] );
unsigned int maxThreshold = atoi( argv[ 3 ] );
typedef ImageSelector < Domain, int>::Type
Image;
Image image = VolReader<Image>::importVol(inputFilename);
SetFromImage<DigitalSet>::append<Image>(set3d, image,
minThreshold, maxThreshold);
trace.
beginBlock(
"Construct the Khalimsky space from the image domain." );
bool space_ok = ks.init( image.domain().lowerBound(),
image.domain().upperBound(), true );
if (!space_ok)
{
trace.
error() <<
"Error in the Khamisky space construction."<<std::endl;
return 2;
}
typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency;
MySurfelAdjacency surfAdj( true );
trace.
beginBlock(
"Extracting boundary by tracking from an initial bel." );
KSpace::SCellSet boundary;
SCell bel = Surfaces<KSpace>::findABel( ks, set3d, 100000 );
Surfaces<KSpace>::trackBoundary( boundary, ks,
surfAdj,
set3d, bel );
QApplication application(argc,argv);
Viewer3D<> viewer( ks );
viewer.show();
viewer << SetMode3D( bel.className(), "Basic" );
viewer << CustomColors3D(Color(250, 0, 0 ), Color( 128, 128, 128 ) );
unsigned long nbSurfels = 0;
for ( KSpace::SCellSet::const_iterator it = boundary.begin(),
it_end = boundary.end(); it != it_end; ++it, ++nbSurfels )
viewer << *it;
viewer << Viewer3D<>::updateDisplay;
trace.
info() <<
"nb surfels = " << nbSurfels << std::endl;
return application.exec();
}
void usage(int, char **argv)
void beginBlock(const std::string &keyword="")
DGtal is the top-level namespace which contains all DGtal functions and types.
int main(int argc, char **argv)
ImageContainerBySTLVector< Domain, Value > Image
Z2i::DigitalSet DigitalSet