32 #include <boost/lexical_cast.hpp>
45 template <
typename S,
typename P,DGtal::u
int32_t p,
typename IntLong>
49 myDomain(aDomain), myPointPredicate(aPredicate)
57 template <
typename S,
typename P,DGtal::u
int32_t p,
typename IntLong>
66 template <
typename S,
typename P,DGtal::u
int32_t p,
typename IntLong>
71 typename Point::UnsignedComponent maxExtent = ( myDomain.upperBound() -
72 myDomain.lowerBound() ).normInfinity();
77 if (SeparableMetric::p != 0)
78 bitSize = SeparableMetric::p * (log ((
double) S::dimension * 2 * maxExtent ) / log(2.0));
84 trace.
warning() <<
"(DistanceTransformation) The output image value range may"
85 <<
" not be sufficient to store the exact values according to"
86 <<
" the input domain extent." << endl;
93 template <
typename S,
typename P, DGtal::u
int32_t p,
typename IntLong>
100 checkTypesValidity ( );
103 myLowerBoundCopy =
Point();
104 myUpperBoundCopy = myDomain.upperBound() - myDomain.lowerBound();
105 myDisplacementVector = myDomain.lowerBound();
107 myExtent = myUpperBoundCopy - myLowerBoundCopy;
108 myInfinity = myMetric.power(static_cast<typename S::Integer>(S::dimension) *
109 myExtent.normInfinity() + 1);
111 Domain workingDomain(myLowerBoundCopy, myUpperBoundCopy);
117 computeFirstStep ( output );
120 for (
Dimension dim = 1; dim < S::dimension ; dim++ )
123 computeOtherSteps ( output, swap, dim );
125 computeOtherSteps ( swap, output, dim );
145 template <
typename S,
typename P,DGtal::u
int32_t p,
typename IntLong>
151 Point startingPoint = myLowerBoundCopy;
158 std::vector<Size> subdomain;
159 subdomain.reserve(S::dimension - 1);
160 for (
Dimension k = S::dimension-1; k>0 ; --k)
161 subdomain.push_back( k );
163 Domain localDomain(myLowerBoundCopy, myUpperBoundCopy);
166 for (ConstDomIt it = localDomain.
subRange( subdomain ).
begin(),
167 itend = localDomain.
subRange( subdomain ).
end(); it != itend; ++it)
170 computeFirstStep1D (output, (*it) );
177 template <
typename S,
typename P,DGtal::u
int32_t p,
typename IntLong>
184 std::string title =
"DT dimension " + boost::lexical_cast<
string>( dim ) ;
193 std::vector<Size> subdomain;
194 subdomain.reserve(S::dimension - 1);
195 for (
unsigned int k = 0; k < S::dimension ; k++)
196 if ( (S::dimension - 1 - k) != dim)
197 subdomain.push_back( S::dimension - 1 - k );
199 Domain localDomain(myLowerBoundCopy, myUpperBoundCopy);
200 Size maxSize = myExtent.normInfinity();
210 for (ConstDomIt it = localDomain.
subRange( subdomain ).
begin(),
214 computeOtherStep1D ( input, output, (*it), dim, s, t );
225 template <
typename S,
typename P,DGtal::u
int32_t p,
typename IntLong>
228 const Point &startingPoint )
const
230 Point prec = startingPoint;
231 Point point = startingPoint;
235 if ( myPointPredicate ( point + myDisplacementVector ) )
236 output.
setValue ( point, myInfinity );
241 for ( point[0] = 1; point[0] <= myUpperBoundCopy[0]; point[0]++ )
244 if ( myPointPredicate ( point + myDisplacementVector ))
245 output.
setValue ( point, 1 + output ( prec ) );
254 prec[0] = myUpperBoundCopy[0];
257 for ( point[0] = myUpperBoundCopy[0] - 1; point[0] >= 0 ; point[0]-- )
259 if ( output ( prec ) < output ( point ) )
260 output.
setValue ( point, 1 + output ( prec ) );
265 for ( point[0] = 0; point[0] <= myUpperBoundCopy[0]; point[0]++ )
266 if (output( point ) < myInfinity)
267 output.
setValue ( point, myMetric.power( (
const int)output ( point ) ));
269 output.
setValue ( point, myInfinity);
275 template <
typename S,
typename P, DGtal::u
int32_t p,
typename IntLong>
279 const Point &startingPoint,
287 Point sQ = startingPoint;
288 Point pU = startingPoint;
292 pU[dim] = myLowerBoundCopy[dim];
293 while ((pU[dim] <= myUpperBoundCopy[dim]) && (input ( pU ) == myInfinity))
298 if ( pU[dim] > myUpperBoundCopy[dim] )
301 itend=output.
spanEnd(startingPoint,dim);
311 t[q] = myLowerBoundCopy[dim];
315 for (
Abscissa u = pU[dim] + 1; u <= myUpperBoundCopy[dim] ; u++ )
318 if ( input( pU ) == myInfinity )
323 while ( ( q >= 0 ) &&
324 ( myMetric.F ( t[q], s[q], input ( sQ ) ) >
325 myMetric.F ( t[q], u, input ( pU ) ) ) )
338 t[0] = myLowerBoundCopy[dim];
343 w = 1 + myMetric.Sep ( s[q],
348 if (( w <= myUpperBoundCopy[dim] )
349 && (w>= myLowerBoundCopy[dim]))
359 Point last = startingPoint;
366 for (last[dim] = myUpperBoundCopy[dim];
367 last[dim] >= myLowerBoundCopy[dim] ;
370 output.
setValue ( last, myMetric.F ( last[dim] , s[q], input ( sQ ) ) );
371 if (( last[dim] == t[q] ) && (q > 0))