DGtal  1.5.beta
testDigitalSurfaceRegularization.cpp
Go to the documentation of this file.
1 
30 #include <iostream>
31 #include "DGtal/base/Common.h"
32 #include "ConfigTest.h"
33 #include "DGtalCatch.h"
34 #include "DGtal/helpers/StdDefs.h"
35 #include "DGtal/helpers/Shortcuts.h"
36 #include "DGtal/helpers/ShortcutsGeometry.h"
37 #include "DGtal/geometry/surfaces/DigitalSurfaceRegularization.h"
39 
40 using namespace std;
41 using namespace DGtal;
42 
44 // Functions for testing class DigitalSurfaceRegularization.
46 
47 TEST_CASE( "Testing DigitalSurfaceRegularization" )
48 {
52  auto params = SH3::defaultParameters()
53  | SHG3::defaultParameters();
54 
55  params( "polynomial", "goursat" )( "gridstep", 1.0)("verbose", 0);
56  auto implicit_shape = SH3::makeImplicitShape3D ( params );
57  auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
58  auto K = SH3::getKSpace( params );
60 
61  SECTION("Basic Construction using Trivial Normals and regular/clamped advection")
62  {
64  auto surface = SH3::makeDigitalSurface( digitized_shape, K, params );
65  auto surfels = SH3::getSurfelRange( surface, params );
67  regul.init();
70  double energy = regul.computeGradient();
71  CAPTURE( regul );
72  REQUIRE( energy == Approx(1684.340));
74  auto finalenergy = regul.regularize();
76  REQUIRE( finalenergy == Approx( 4.7763 ) );
77  REQUIRE( regul.isValid() );
78 
80  auto regularizedPosition = regul.getRegularizedPositions();
81  auto original = regul.getOriginalPositions();
83  auto normals = regul.getNormalVectors();
84 
85  auto cellIndex = regul.getCellIndex();
86  SH3::saveOBJ(surface, [&] (const SH3::Cell &c){ return original[ cellIndex[c]];},
87  normals, SH3::Colors(), "originalSurf.obj");
88  SH3::saveOBJ(surface, [&] (const SH3::Cell &c){ return regularizedPosition[ cellIndex[c]];},
89  normals, SH3::Colors(), "regularizedSurf.obj");
90 
91  //Testing reset() at few points
92  regul.reset();
93  regularizedPosition = regul.getRegularizedPositions();
94  REQUIRE( original[0] == regularizedPosition[0] );
95  REQUIRE( original[123] == regularizedPosition[123] );
96 
97  //Testing Clamped version
98  auto finalenergyClamped = regul.regularize(200,1.0,0.001, DigitalSurfaceRegularization<SH3::DigitalSurface>::clampedAdvection);
99  regularizedPosition = regul.getRegularizedPositions();
100  SH3::saveOBJ(surface, [&] (const SH3::Cell &c){ return regularizedPosition[ cellIndex[c]];},
101  normals, SH3::Colors(), "regularizedSurfClamped.obj");
102  REQUIRE( finalenergyClamped == Approx(12.1914) );
103  REQUIRE( finalenergy < finalenergyClamped );
104 
105  //Testing accessor
106  auto aPointelIndex = cellIndex.begin();
107  REQUIRE( regularizedPosition[ aPointelIndex->second ] == regul.getRegularizedPosition( aPointelIndex->first) );
108  }
109 
110  SECTION("Basic Construction with II Normal Vectors")
111  {
112  auto surface = SH3::makeDigitalSurface( digitized_shape, K, params );
113  auto surfels = SH3::getSurfelRange( surface, params );
115  auto ii_normals = SHG3::getIINormalVectors(digitized_shape, surfels, params);
117  regul.init();
118  auto surfelIndex = regul.getSurfelIndex();
119  regul.attachNormalVectors([&](SH3::SCell &c){ return ii_normals[ surfelIndex[c] ];} );
121 
122  double energy = regul.computeGradient();
123  CAPTURE( regul );
124  REQUIRE( energy == Approx(1588.649));
125  regul.regularize();
126  REQUIRE( regul.isValid() );
127 
128  auto regularizedPosition = regul.getRegularizedPositions();
129  auto normals = regul.getNormalVectors();
130  auto cellIndex = regul.getCellIndex();
131  SH3::saveOBJ(surface, [&] (const SH3::Cell &c){ return regularizedPosition[ cellIndex[c]];},
132  normals, SH3::Colors(), "regularizedSurf-II.obj");
133  }
134 
135  SECTION("Warm restart")
136  {
137  auto surface = SH3::makeDigitalSurface( digitized_shape, K, params );
138  auto surfels = SH3::getSurfelRange( surface, params );
140  regul.init();
142  CAPTURE( regul );
143  auto energy = regul.regularize(10,1.0,0.1);
144  auto secondenergy = regul.regularize(10,1.0,0.1);
145  auto thirdenergy = regul.regularize(10,1.0,0.1);
146  CAPTURE(energy);
147  CAPTURE(secondenergy);
148  CAPTURE(thirdenergy);
149 
150  REQUIRE( energy > secondenergy );
151  REQUIRE( secondenergy > thirdenergy );
152  }
153 
154  SECTION("Local weights")
155  {
156  auto surface = SH3::makeDigitalSurface( digitized_shape, K, params );
157  auto surfels = SH3::getSurfelRange( surface, params );
159  regul.init();
161  CAPTURE( regul );
162  auto energy = regul.regularize(10,1.0,0.1);
163 
164  auto original = regul.getOriginalPositions();
165  std::vector<double> alphas(original.size(),0.001);
166  std::vector<double> betas(original.size(),1.0);
167  std::vector<double> gammas(original.size(), 0.05);
168 
169  //Init again with variable (but constant) weights
171  regul2.init(alphas,betas,gammas);
173  auto energybis = regul2.regularize(10,1.0,0.1);
174  REQUIRE( energy == energybis );
175 
176  energybis = regul2.regularize();
177  auto regularizedPosition = regul.getRegularizedPositions();
178  auto normals = regul.getNormalVectors();
179  auto cellIndex = regul.getCellIndex();
180  SH3::saveOBJ(surface, [&] (const SH3::Cell &c){ return regularizedPosition[ cellIndex[c]];},
181  normals, SH3::Colors(), "regularizedSurf-local.obj");
182 
183  //Same with higher data attachment for x < 0.0
186  for(size_t i = 0 ; i < original.size(); ++i)
187  if (original[i][0]<0.0)
188  {
189  alphas[i] = 4.0;
190  betas[i] = 0.0000001;
191  gammas[i] = 0.0;
192  }
193  regul3.init(alphas,betas,gammas);
194  regul3.attachConvolvedTrivialNormalVectors(params);
195  energybis = regul3.regularize();
197 
198  regularizedPosition = regul3.getRegularizedPositions();
199  SH3::saveOBJ(surface, [&] (const SH3::Cell &c){ return regularizedPosition[ cellIndex[c]];},
200  normals, SH3::Colors(), "regularizedSurf-localsplit.obj");
201  }
202 }
203 
Aim: Implements Digital Surface Regularization as described in .
void init(const double alpha=0.001, const double beta=1.0, const double gamma=0.05)
Initialize the parameters of the energy function.
void attachConvolvedTrivialNormalVectors(const Parameters someParams=SH3::defaultParameters()|SHG3::defaultParameters())
void attachNormalVectors(const std::function< SHG3::RealVector(SH3::SCell &)> &normalFunc)
const SH3::Surfel2Index & getSurfelIndex() const
SHG3::RealPoint getRegularizedPosition(const SH3::Cell &aPointel)
double regularize(const unsigned int nbIters, const double dt, const double epsilon, const AdvectionFunction &advectionFunc)
Main regularization loop.
const SH3::Cell2Index & getCellIndex() const
Aim: This class is used to simplify shape and surface creation. With it, you can create new shapes an...
Aim: This class is used to simplify shape and surface creation. With it, you can create new shapes an...
Definition: Shortcuts.h:105
std::vector< Color > Colors
Definition: Shortcuts.h:192
LightDigitalSurface::SCell SCell
Definition: Shortcuts.h:163
LightDigitalSurface::Cell Cell
Definition: Shortcuts.h:162
CountedPtr< SH3::DigitalSurface > surface
DGtal is the top-level namespace which contains all DGtal functions and types.
Shortcuts< KSpace > SH3
CAPTURE(thicknessHV)
KSpace K
TEST_CASE("Testing DigitalSurfaceRegularization")
ShortcutsGeometry< Z3i::KSpace > SHG3
SECTION("Testing constant forward iterators")
REQUIRE(domain.isInside(aPoint))