2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file VoronoiCovarianceMeasureOnDigitalSurface.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
24 * Implementation of inline methods defined in VoronoiCovarianceMeasureOnDigitalSurface.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 #include "DGtal/topology/CanonicSCellEmbedder.h"
33 #include "DGtal/math/ScalarFunctors.h"
34 #include "DGtal/geometry/surfaces/estimation/LocalEstimatorFromSurfelFunctorAdapter.h"
35 #include "DGtal/geometry/surfaces/estimation/estimationFunctors/ElementaryConvolutionNormalVectorEstimator.h"
37 //////////////////////////////////////////////////////////////////////////////
39 ///////////////////////////////////////////////////////////////////////////////
40 // IMPLEMENTATION of inline methods.
41 ///////////////////////////////////////////////////////////////////////////////
43 ///////////////////////////////////////////////////////////////////////////////
44 // ----------------------- Standard services ------------------------------
46 //-----------------------------------------------------------------------------
47 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
49 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
50 ~VoronoiCovarianceMeasureOnDigitalSurface()
53 //-----------------------------------------------------------------------------
54 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
56 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
57 VoronoiCovarianceMeasureOnDigitalSurface( ConstAlias< Surface > _surface,
58 Surfel2PointEmbedding _surfelEmbedding,
61 Scalar t, Metric aMetric, bool verbose )
62 : mySurface( _surface ), mySurfelEmbedding( _surfelEmbedding ), myChi( chi_r ),
63 myVCM( _R, _r, aMetric, verbose ), myRadiusTrivial( t )
65 if ( verbose ) trace.beginBlock( "Computing VCM on digital surface." );
66 const KSpace & ks = mySurface->container().space();
67 std::vector<Point> vectPoints;
70 if ( verbose ) trace.beginBlock( "Getting points." );
71 std::set<Point> pointSet;
72 for ( ConstIterator it = mySurface->begin(), itE = mySurface->end(); it != itE; ++it )
73 getPoints( std::inserter( pointSet, pointSet.begin() ), *it );
74 vectPoints.resize( pointSet.size() );
75 std::copy( pointSet.begin(), pointSet.end(), vectPoints.begin() );
77 if ( verbose ) trace.endBlock();
79 // Compute Voronoi Covariance Matrix for all points.
80 myVCM.init( vectPoints.begin(), vectPoints.end() );
82 // Compute VCM( chi_r ) for each point.
83 if ( verbose ) trace.beginBlock ( "Integrating VCM( chi_r(p) ) for each point." );
85 // HatPointFunction< Point, Scalar > chi_r( 1.0, r );
86 for ( typename std::vector<Point>::const_iterator it = vectPoints.begin(), itE = vectPoints.end();
89 if ( verbose ) trace.progressBar( ++i, vectPoints.size() );
91 MatrixNN measure = myVCM.measure( myChi, p );
92 // On diagonalise le résultat.
93 EigenStructure & evcm = myPt2EigenStructure[ p ];
94 LinearAlgebraTool::getEigenDecomposition( measure, evcm.vectors, evcm.values );
96 myVCM.clean(); // free some memory.
97 if ( verbose ) trace.endBlock();
99 if ( verbose ) trace.beginBlock ( "Computing average orientation for each surfel." );
100 typedef functors::HatFunction<Scalar> Functor;
101 Functor fct( 1.0, myRadiusTrivial );
102 typedef functors::ElementaryConvolutionNormalVectorEstimator< Surfel, CanonicSCellEmbedder<KSpace> >
104 typedef LocalEstimatorFromSurfelFunctorAdapter< DigitalSurfaceContainer, Metric, SurfelFunctor, Functor>
107 CanonicSCellEmbedder<KSpace> canonic_embedder( ks );
108 SurfelFunctor surfelFct( canonic_embedder, 1.0 );
109 NormalEstimator estimator;
110 estimator.attach( *mySurface);
111 estimator.setParams( aMetric, surfelFct, fct , myRadiusTrivial);
112 estimator.init( 1.0, mySurface->begin(), mySurface->end());
114 std::vector<Point> pts;
115 int surf_size = mySurface->size();
116 for ( ConstIterator it = mySurface->begin(), itE = mySurface->end(); it != itE; ++it )
118 if ( verbose ) trace.progressBar(++i, surf_size );
120 Normals & normals = mySurfel2Normals[ s ];
121 // get rough estimation of normal
122 normals.trivialNormal = estimator.eval( it );
123 // get points associated with surfel s
124 getPoints( std::back_inserter( pts ), s );
125 for ( typename std::vector<Point>::const_iterator itPts = pts.begin(), itPtsE = pts.end();
126 itPts != itPtsE; ++itPts )
129 const EigenStructure& evcm = myPt2EigenStructure[ p ];
130 VectorN n = evcm.vectors.column( Space::dimension-1 );
131 if ( n.dot( normals.trivialNormal ) < 0 ) normals.vcmNormal -= n;
132 else normals.vcmNormal += n;
134 if ( pts.size() > 1 ) normals.vcmNormal /= pts.size();
137 if ( verbose ) trace.endBlock();
139 if ( verbose ) trace.endBlock();
142 //-----------------------------------------------------------------------------
143 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
145 DGtal::CountedConstPtrOrConstPtr< typename DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::Surface >
146 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
151 //-----------------------------------------------------------------------------
152 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
154 DGtal::Surfel2PointEmbedding
155 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
156 surfelEmbedding() const
158 return mySurfelEmbedding;
160 //-----------------------------------------------------------------------------
161 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
163 typename DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::Scalar
164 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
169 //-----------------------------------------------------------------------------
170 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
172 typename DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::Scalar
173 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
178 //-----------------------------------------------------------------------------
179 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
181 typename DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::Scalar
182 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
183 radiusTrivial() const
185 return myRadiusTrivial;
187 //-----------------------------------------------------------------------------
188 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
190 const typename DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::Surfel2Normals&
191 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
192 mapSurfel2Normals() const
194 return mySurfel2Normals;
196 //-----------------------------------------------------------------------------
197 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
199 const typename DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::Point2EigenStructure&
200 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
201 mapPoint2ChiVCM() const
203 return myPt2EigenStructure;
206 //-----------------------------------------------------------------------------
207 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
210 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
211 getChiVCMEigenvalues( VectorN& values, Surfel s ) const
213 std::vector<Point> pts;
214 getPoints( std::back_inserter( pts ), s );
217 values = VectorN(); // Setting values to 0 before averaging.
218 for ( typename std::vector<Point>::const_iterator itPts = pts.begin(), itPtsE = pts.end();
219 itPts != itPtsE; ++itPts, ++i )
222 typename Point2EigenStructure::const_iterator itEigen = myPt2EigenStructure.find( p );
223 if ( itEigen == myPt2EigenStructure.end() )
228 const EigenStructure& evcm = itEigen->second;
229 values += evcm.values;
231 if ( i > 1 ) values /= i;
235 //-----------------------------------------------------------------------------
236 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
239 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
240 getChiVCMEigenStructure( VectorN& values, MatrixNN& vectors, Surfel s ) const
242 std::vector<Point> pts;
243 getPoints( std::back_inserter( pts ), s );
246 values = VectorN(); // Setting values to 0 before averaging.
247 vectors = MatrixNN(); // Setting values to 0 before averaging.
248 for ( typename std::vector<Point>::const_iterator itPts = pts.begin(), itPtsE = pts.end();
249 itPts != itPtsE; ++itPts, ++i )
252 typename Point2EigenStructure::const_iterator itEigen = myPt2EigenStructure.find( p );
253 if ( itEigen == myPt2EigenStructure.end() )
258 const EigenStructure& evcm = itEigen->second;
259 values += evcm.values;
260 vectors += evcm.vectors;
269 //-----------------------------------------------------------------------------
270 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
271 template <typename PointOutputIterator>
274 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
275 getPoints( PointOutputIterator outIt, Surfel s ) const
277 BOOST_CONCEPT_ASSERT(( boost::OutputIterator< PointOutputIterator, Point > ));
278 const KSpace & ks = mySurface->container().space();
279 Dimension k = ks.sOrthDir( s );
280 switch ( mySurfelEmbedding ) {
283 typename KSpace::Cells faces = ks.uFaces( ks.unsigns( s ) );
284 for ( typename KSpace::Cells::const_iterator it = faces.begin(), itE = faces.end();
287 if ( ks.uDim( *it ) == 0 ) // get only pointels (cell of dim 0)
288 *outIt++ = ks.uCoords( *it );
290 // Dimension i = (k+1)%3;
291 // Dimension j = (i+1)%3;
292 // SCell l1 = ks.sIncident( s, i, true );
293 // SCell l2 = ks.sIncident( s, i, false );
294 // *outIt++ = ks.sCoords( ks.sIncident( l1, j, true ) );
295 // *outIt++ = ks.sCoords( ks.sIncident( l1, j, false ) );
296 // *outIt++ = ks.sCoords( ks.sIncident( l2, j, true ) );
297 // *outIt++ = ks.sCoords( ks.sIncident( l2, j, false ) );
301 *outIt++ = ks.sCoords( ks.sDirectIncident( s, k ) );
304 *outIt++ = ks.sCoords( ks.sIndirectIncident( s, k ) );
310 ///////////////////////////////////////////////////////////////////////////////
311 // Interface - public :
314 * Writes/Displays the object on an output stream.
315 * @param out the output stream where the object is written.
317 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
320 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
321 selfDisplay ( std::ostream & out ) const
323 out << "[VoronoiCovarianceMeasureOnDigitalSurface"
324 << " #pts=" << myPt2EigenStructure.size()
325 << " #surf=" << mySurfel2Normals.size()
330 * Checks the validity/consistency of the object.
331 * @return 'true' if the object is valid, 'false' otherwise.
333 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
336 DGtal::VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction>::
344 ///////////////////////////////////////////////////////////////////////////////
345 // Implementation of inline functions //
347 template <typename TDigitalSurfaceContainer, typename TSeparableMetric, typename TKernelFunction>
350 DGtal::operator<< ( std::ostream & out,
351 const VoronoiCovarianceMeasureOnDigitalSurface<TDigitalSurfaceContainer, TSeparableMetric, TKernelFunction> & object )
353 object.selfDisplay( out );
358 ///////////////////////////////////////////////////////////////////////////////