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 IntegralInvariantVolumeEstimator.ih
19 * @author Jeremy Levallois (\c jeremy.levallois@liris.cnrs.fr )
20 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), INSA-Lyon, France
21 * LAboratoire de MAthématiques - LAMA (CNRS, UMR 5127), Université de Savoie, France
22 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
23 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
27 * Implementation of inline methods defined in IntegralInvariantVolumeEstimator.h
29 * This file is part of the DGtal library.
33//////////////////////////////////////////////////////////////////////////////
35#include "DGtal/math/BasicMathFunctions.h"
36//////////////////////////////////////////////////////////////////////////////
38///////////////////////////////////////////////////////////////////////////////
39// IMPLEMENTATION of inline methods.
40///////////////////////////////////////////////////////////////////////////////
42///////////////////////////////////////////////////////////////////////////////
43// ----------------------- Standard services ------------------------------
45//-----------------------------------------------------------------------------
46template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
48DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
49~IntegralInvariantVolumeEstimator()
54//-----------------------------------------------------------------------------
55template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
58DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
61 for( unsigned int i = 0; i < myKernelsSet.size(); ++i )
62 if ( myKernelsSet[ i ] != 0 ) delete myKernelsSet[ i ];
66//-----------------------------------------------------------------------------
67template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
69DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
70IntegralInvariantVolumeEstimator( VolumeFunctor fct )
72 myKernelFunctor(NumberTraits<Value>::ONE),
73 myKernels(), myKernelsSet(),
74 myKernel( 0 ), myDigKernel( 0 ),
75 myPointPredicate( 0 ), myShapeDomain( 0 ),
76 myShapePointFunctor( 0 ), myShapeSpelFunctor( 0 ),
78 myH( 1.0 ), myRadius( 0.0 )
82//-----------------------------------------------------------------------------
83template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
85DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
86IntegralInvariantVolumeEstimator
87( ConstAlias< KSpace > K,
88 ConstAlias< PointPredicate > aPointPredicate,
91 myKernelFunctor(NumberTraits<Value>::ONE),
92 myKernels(), myKernelsSet(),
93 myKernel( 0 ), myDigKernel( 0 ),
94 myPointPredicate( aPointPredicate ), myShapeDomain( 0 ),
95 myShapePointFunctor( 0 ), myShapeSpelFunctor( 0 ),
97 myH( 1.0 ), myRadius( 0.0 )
99 CountedConstPtrOrConstPtr<KSpace> ptrK( K );
100 myShapeDomain = CountedPtr<Domain>( new Domain( ptrK->lowerBound(), ptrK->upperBound() ) );
101 myShapePointFunctor = CountedPtr<ShapePointFunctor>( new ShapePointFunctor( *myPointPredicate, *myShapeDomain, 1, 0 ) );
102 myShapeSpelFunctor = CountedPtr<ShapeSpelFunctor>( new ShapeSpelFunctor( *myShapePointFunctor, K ) );
103 myConvolver = CountedPtr<Convolver>( new Convolver( *myShapeSpelFunctor, myKernelFunctor, K ) );
106//-----------------------------------------------------------------------------
107template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
109DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
110IntegralInvariantVolumeEstimator
112 : myFct( other.myFct ),
113 myKernelFunctor( other.myKernelFunctor ),
114 myKernels( other.myKernels ), myKernelsSet( other.myKernelsSet ),
115 myKernel( other.myKernel ), myDigKernel( other.myDigKernel ),
116 myPointPredicate( other.myPointPredicate ), myShapeDomain( other.myShapeDomain ),
117 myShapePointFunctor( other.myShapePointFunctor ), myShapeSpelFunctor( other.myShapeSpelFunctor ),
118 myConvolver( other.myConvolver ),
119 myH( other.myH ), myRadius( other.myRadius )
121//-----------------------------------------------------------------------------
122template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
124typename DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::Self&
125DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
126operator= ( const Self& other )
128 if ( this != &other )
131 // myKernelFunctor = other.myKernelFunctor;
132 myKernels = other.myKernels;
133 myKernelsSet = other.myKernelsSet;
134 myKernel = other.myKernel;
135 myDigKernel = other.myDigKernel;
136 myPointPredicate = other.myPointPredicate;
137 myShapeDomain = other.myShapeDomain;
138 myShapePointFunctor = other.myShapePointFunctor;
139 myShapeSpelFunctor = other.myShapeSpelFunctor;
140 myConvolver = other.myConvolver;
142 myRadius = other.myRadius;
146//-----------------------------------------------------------------------------
147template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
149typename DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::Scalar
150DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
155//-----------------------------------------------------------------------------
156template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
159DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
161( ConstAlias< KSpace > K,
162 ConstAlias<PointPredicate> aPointPredicate )
164 myPointPredicate = aPointPredicate;
165 CountedConstPtrOrConstPtr<KSpace> ptrK( K );
166 myShapeDomain = CountedPtr<Domain>( new Domain( ptrK->lowerBound(), ptrK->upperBound() ) );
167 myShapePointFunctor = CountedPtr<ShapePointFunctor>( new ShapePointFunctor( *myPointPredicate, *myShapeDomain, 1, 0 ) );
168 myShapeSpelFunctor = CountedPtr<ShapeSpelFunctor>( new ShapeSpelFunctor( *myShapePointFunctor, K ) );
169 myConvolver = CountedPtr<Convolver>( new Convolver( *myShapeSpelFunctor, myKernelFunctor, K ) );
171//-----------------------------------------------------------------------------
172template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
175DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
177( const double dRadius )
179 ASSERT( ( dRadius > 0.0 )
180 && "[DGtal::IntegralInvariantVolumeEstimator:setParams] Radius parameter dRadius must be positive." );
184//-----------------------------------------------------------------------------
185template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
186template <typename SurfelConstIterator>
189DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
191( const double _h, SurfelConstIterator /* itb */, SurfelConstIterator /* ite */ )
194 && "[DGtal::IntegralInvariantVolumeEstimator:init] Gridstep parameter h must be positive." );
195 ASSERT( ( myRadius > 0.0 )
196 && "[DGtal::IntegralInvariantVolumeEstimator:init] Radius parameter dRadius must have been initialized with a call to 'setParams'." );
197 ASSERT( ( myConvolver != 0 )
198 && "[DGtal::IntegralInvariantVolumeEstimator:init] Shape of interest must have been initialized with a call to 'attach'." );
200 typedef typename RealPoint::Component ScalarC;
202 for( unsigned int i = 0; i < myKernelsSet.size(); ++i )
203 if ( myKernelsSet[ i ] != 0 ) delete myKernelsSet[ i ];
206 double eRadius = myRadius * myH; // Euclidean radius of the ball kernel.
208 myFct.init( myH, eRadius );
210 RealPoint rOrigin = RealPoint::zero;
211 Point pOrigin = Point::zero;
212 myKernel = CountedPtr<KernelSupport>( new KernelSupport( rOrigin, eRadius ) ); // acquired
213 myDigKernel = CountedPtr<DigitalShapeKernel>( new DigitalShapeKernel() );
214 myDigKernel->attach( *myKernel );
215 myDigKernel->init( myKernel->getLowerBound() + Point::diagonal(-1), myKernel->getUpperBound() + Point::diagonal(1), myH );
216 Domain neighborhood( Point::diagonal(-1), Point::diagonal(1) );
217 unsigned int n = functions::power( (unsigned int) 3, Space::dimension );
218 myKernels = std::vector< PairIterators > ( n );
219 myKernelsSet = std::vector< DigitalSet* >( n );
220 unsigned int offset = 0;
221 unsigned int middle = n / 2;
222 RealPoint shiftPoint;
223 for ( typename Domain::ConstIterator it_neigh = neighborhood.begin(),
224 it_neigh_end = neighborhood.end();
225 it_neigh != it_neigh_end;
226 ++it_neigh, ++offset )
228 /// Computation of shifting masks
229 if( offset == middle ) continue; // no shift
230 for ( Dimension k = 0; k < Space::dimension; ++k )
231 shiftPoint[ k ] = (ScalarC) (*it_neigh)[ k ];
232 shiftPoint *= (ScalarC) myH;
233 KernelSupport* kernelShifted = new KernelSupport( shiftPoint, eRadius );
234 EuclideanMinus* current = new EuclideanMinus( myKernel );
235 current->minus( kernelShifted );
236 DigitalShape digCurrent;
237 digCurrent.attach( *current );
238 digCurrent.init( myKernel->getLowerBound() + Point::diagonal(-1), myKernel->getUpperBound() + Point::diagonal(1), myH );
240 myKernelsSet[ offset ] = new DigitalSet( digCurrent.getDomain() );
241 Shapes< Domain>::digitalShaper ( *(myKernelsSet[ offset ]), digCurrent );
243 myKernels[ offset ].first = myKernelsSet[ offset ]->begin();
244 myKernels[ offset ].second = myKernelsSet[ offset ]->end();
247 delete kernelShifted;
249 /// End of computation of masks
250 myConvolver->init( pOrigin, *myDigKernel, myKernels );
253//-----------------------------------------------------------------------------
254template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
255template <typename SurfelConstIterator>
257typename DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::Quantity
258DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
260( SurfelConstIterator it ) const
262 return myFct( myConvolver->eval( it ) );
265//-----------------------------------------------------------------------------
266template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
267template <typename OutputIterator, typename SurfelConstIterator>
270DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::eval
271( SurfelConstIterator itb,
272 SurfelConstIterator ite,
273 OutputIterator result ) const
275 myConvolver->eval( itb, ite, result, myFct );
279//-----------------------------------------------------------------------------
280template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
283DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::selfDisplay
284( std::ostream & out ) const
286 out << "[IntegralInvariantVolumeEstimator h=" << myH
287 << " digR=" << myRadius << " eucR=" << (myH*myRadius) << " ]";
290//-----------------------------------------------------------------------------
291template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
294DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::isValid() const
296 return ( myH > 0 ) && ( myRadius > 0 ) && ( myConvolver != 0 );
299//-----------------------------------------------------------------------------
300template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
305 const IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor> & object )
307 object.selfDisplay( out );