This example shows the computation of the VCM of a digital surface read from a .vol file. The normal is estimated from the diagonalization of the VCM tensor, while the orientation is deduced from the orientation of the trivial surfel normals. Feature detection is achieved with the eigenvalues of the VCM. A red color indicates a feature. Normals are displayed as black lines.
#include <iostream>
#include "DGtal/base/Common.h"
#include "DGtal/helpers/StdDefs.h"
#include "DGtal/kernel/BasicPointPredicates.h"
#include "DGtal/math/linalg/EigenDecomposition.h"
#include "DGtal/topology/helpers/Surfaces.h"
#include "DGtal/topology/DigitalSurface.h"
#include "DGtal/topology/ImplicitDigitalSurface.h"
#include "DGtal/images/ImageSelector.h"
#include "DGtal/images/IntervalForegroundPredicate.h"
#include "DGtal/geometry/volumes/distance/ExactPredicateLpSeparableMetric.h"
#include "DGtal/geometry/surfaces/estimation/VoronoiCovarianceMeasureOnDigitalSurface.h"
#include "DGtal/io/colormaps/GradientColorMap.h"
#include "DGtal/io/viewers/Viewer3D.h"
#include "DGtal/io/readers/GenericReader.h"
#include "ConfigExamples.h"
using namespace std;
int main(
int argc,
char** argv )
{
QApplication application(argc,argv);
typedef HyperRectDomain<Space>
Domain;
typedef functors::IntervalForegroundPredicate<Image> ThresholdedImage;
typedef ImplicitDigitalSurface< KSpace, ThresholdedImage > DigitalSurfaceContainer;
typedef ExactPredicateLpSeparableMetric<Space, 2> Metric;
typedef functors::HatPointFunction<Point,double> KernelFunction;
typedef VoronoiCovarianceMeasureOnDigitalSurface< DigitalSurfaceContainer, Metric,
KernelFunction > VCMOnSurface;
typedef VCMOnSurface::Surfel2Normals::const_iterator S2NConstIterator;
string inputFilename = examplesPath + "samples/Al.100.vol";
trace.
info() <<
"File = " << inputFilename << std::endl;
int thresholdMin = 0;
trace.
info() <<
"Min image thres. = " << thresholdMin << std::endl;
int thresholdMax = 1;
trace.
info() <<
"Max image thres. = " << thresholdMax << std::endl;
const double R = 20;
trace.
info() <<
"Big radius R = " << R << std::endl;
const double r = 3;
trace.
info() <<
"Small radius r = " << r << std::endl;
const double trivial_r = 3;
trace.
info() <<
"Trivial radius t = " << trivial_r << std::endl;
const double T = 0.1;
trace.
info() <<
"Feature thres. T = " << T << std::endl;
const double size = 1.0;
trace.
beginBlock(
"Loading image into memory and build digital surface." );
Image image = GenericReader<Image>::import(inputFilename );
ThresholdedImage thresholdedImage( image, thresholdMin, thresholdMax );
ks.init( image.domain().lowerBound(),
image.domain().upperBound(), true );
SurfelAdjacency<KSpace::dimension> surfAdj( true );
Surfel bel = Surfaces<KSpace>::findABel( ks, thresholdedImage, 10000 );
DigitalSurfaceContainer* container =
new DigitalSurfaceContainer( ks, thresholdedImage, surfAdj, bel, false );
DigitalSurface< DigitalSurfaceContainer >
surface( container );
trace.
info() <<
"Digital surface has " <<
surface.size() <<
" surfels." << std::endl;
Metric l2;
KernelFunction chi( 1.0, r );
VCMOnSurface vcm_surface(
surface, embType, R, r,
chi, trivial_r, l2, true );
Viewer3D<> viewer( ks );
viewer.setWindowTitle("3D VCM viewer");
viewer << SetMode3D( dummy.className(), "Basic" );
viewer.show();
GradientColorMap<double> grad( 0, T );
grad.addColor( Color( 128, 128, 255 ) );
grad.addColor( Color( 255, 255, 255 ) );
grad.addColor( Color( 255, 255, 0 ) );
grad.addColor( Color( 255, 0, 0 ) );
RealVector lambda;
for ( S2NConstIterator it = vcm_surface.mapSurfel2Normals().begin(),
itE = vcm_surface.mapSurfel2Normals().end(); it != itE; ++it )
{
Point kp = ks.sKCoords( s );
RealPoint rp( 0.5 * (
double) kp[ 0 ], 0.5 * (
double) kp[ 1 ], 0.5 * (
double) kp[ 2 ] );
RealVector n = it->second.vcmNormal;
vcm_surface.getChiVCMEigenvalues( lambda, s );
double ratio = lambda[ 1 ] / ( lambda[ 0 ] + lambda[ 1 ] + lambda[ 2 ] );
viewer.setFillColor( grad( ratio > T ? T : ratio ) );
viewer << ks.unsigns( s );
n *= size;
viewer.setLineColor( Color::Black );
viewer.addLine( rp + n, rp - n, 0.1 );
}
viewer << Viewer3D<>::updateDisplay;
application.exec();
return 0;
}
void beginBlock(const std::string &keyword="")
CountedPtr< SH3::DigitalSurface > surface
Space::RealVector RealVector
DGtal is the top-level namespace which contains all DGtal functions and types.
Surfel2PointEmbedding
Possible embeddings for surfel as point(s)
ImageContainerBySTLVector< Domain, unsigned char > Type
int main(int argc, char **argv)
ImageContainerBySTLVector< Domain, Value > Image
HyperRectDomain< Space > Domain
PointVector< 3, double > RealPoint