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 //-----------------------------------------------------------------------------
46 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
48 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
49 ~IntegralInvariantVolumeEstimator()
54 //-----------------------------------------------------------------------------
55 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
58 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
61 for( unsigned int i = 0; i < myKernelsSet.size(); ++i )
62 if ( myKernelsSet[ i ] != 0 ) delete myKernelsSet[ i ];
66 //-----------------------------------------------------------------------------
67 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
69 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
70 IntegralInvariantVolumeEstimator( 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 //-----------------------------------------------------------------------------
83 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
85 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
86 IntegralInvariantVolumeEstimator
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 //-----------------------------------------------------------------------------
107 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
109 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
110 IntegralInvariantVolumeEstimator
111 ( const Self& other )
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 //-----------------------------------------------------------------------------
122 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
124 typename DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::Self&
125 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
126 operator= ( 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 //-----------------------------------------------------------------------------
147 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
149 typename DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::Scalar
150 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
155 //-----------------------------------------------------------------------------
156 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
159 DGtal::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 //-----------------------------------------------------------------------------
172 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
175 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
177 ( const double dRadius )
179 ASSERT( ( dRadius > 0.0 )
180 && "[DGtal::IntegralInvariantVolumeEstimator:setParams] Radius parameter dRadius must be positive." );
184 //-----------------------------------------------------------------------------
185 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
186 template <typename SurfelConstIterator>
189 DGtal::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 //-----------------------------------------------------------------------------
254 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
255 template <typename SurfelConstIterator>
257 typename DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::Quantity
258 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::
260 ( SurfelConstIterator it ) const
262 return myFct( myConvolver->eval( it ) );
265 //-----------------------------------------------------------------------------
266 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
267 template <typename OutputIterator, typename SurfelConstIterator>
270 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::eval
271 ( SurfelConstIterator itb,
272 SurfelConstIterator ite,
273 OutputIterator result ) const
275 myConvolver->eval( itb, ite, result, myFct );
279 //-----------------------------------------------------------------------------
280 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
283 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::selfDisplay
284 ( std::ostream & out ) const
286 out << "[IntegralInvariantVolumeEstimator h=" << myH
287 << " digR=" << myRadius << " eucR=" << (myH*myRadius) << " ]";
290 //-----------------------------------------------------------------------------
291 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
294 DGtal::IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor>::isValid() const
296 return ( myH > 0 ) && ( myRadius > 0 ) && ( myConvolver != 0 );
299 //-----------------------------------------------------------------------------
300 template <typename TKSpace, typename TPointPredicate, typename TVolumeFunctor>
304 ( std::ostream & out,
305 const IntegralInvariantVolumeEstimator<TKSpace, TPointPredicate, TVolumeFunctor> & object )
307 object.selfDisplay( out );