@ -448,7 +448,7 @@ static void getDistanceTransformMask( int maskType, float *metrics )
struct DTColumnInvoker : ParallelLoopBody
struct DTColumnInvoker : ParallelLoopBody
{
{
DTColumnInvoker ( const Mat * _src , Mat * _dst , const int * _sat_tab , const floa t* _sqr_tab )
DTColumnInvoker ( const Mat * _src , Mat * _dst , const int * _sat_tab , const in t* _sqr_tab )
{
{
src = _src ;
src = _src ;
dst = _dst ;
dst = _dst ;
@ -481,7 +481,7 @@ struct DTColumnInvoker : ParallelLoopBody
{
{
dist = dist + 1 - sat_tab [ dist - d [ j ] ] ;
dist = dist + 1 - sat_tab [ dist - d [ j ] ] ;
d [ j ] = dist ;
d [ j ] = dist ;
dptr [ 0 ] = sqr_tab [ dist ] ;
dptr [ 0 ] = ( float ) sqr_tab [ dist ] ;
}
}
}
}
}
}
@ -489,12 +489,12 @@ struct DTColumnInvoker : ParallelLoopBody
const Mat * src ;
const Mat * src ;
Mat * dst ;
Mat * dst ;
const int * sat_tab ;
const int * sat_tab ;
const floa t* sqr_tab ;
const in t* sqr_tab ;
} ;
} ;
struct DTRowInvoker : ParallelLoopBody
struct DTRowInvoker : ParallelLoopBody
{
{
DTRowInvoker ( Mat * _dst , const floa t* _sqr_tab , const float * _inv_tab )
DTRowInvoker ( Mat * _dst , const in t* _sqr_tab , const float * _inv_tab )
{
{
dst = _dst ;
dst = _dst ;
sqr_tab = _sqr_tab ;
sqr_tab = _sqr_tab ;
@ -529,7 +529,7 @@ struct DTRowInvoker : ParallelLoopBody
for ( ; ; k - - )
for ( ; ; k - - )
{
{
p = v [ k ] ;
p = v [ k ] ;
float s = ( fq + sqr_tab [ q ] - d [ p ] - sqr_tab [ p ] ) * inv_tab [ q - p ] ;
float s = ( fq - d [ p ] + ( sqr_tab [ q ] - sqr_tab [ p ] ) ) * inv_tab [ q - p ] ;
if ( s > z [ k ] )
if ( s > z [ k ] )
{
{
k + + ;
k + + ;
@ -552,28 +552,28 @@ struct DTRowInvoker : ParallelLoopBody
}
}
Mat * dst ;
Mat * dst ;
const floa t* sqr_tab ;
const in t* sqr_tab ;
const float * inv_tab ;
const float * inv_tab ;
} ;
} ;
static void
static void
trueDistTrans ( const Mat & src , Mat & dst )
trueDistTrans ( const Mat & src , Mat & dst )
{
{
const float inf = 1e15 f ;
const int inf = INT_MAX ;
CV_Assert ( src . size ( ) = = dst . size ( ) ) ;
CV_Assert ( src . size ( ) = = dst . size ( ) ) ;
CV_Assert ( src . type ( ) = = CV_8UC1 & & dst . type ( ) = = CV_32FC1 ) ;
CV_Assert ( src . type ( ) = = CV_8UC1 & & dst . type ( ) = = CV_32FC1 ) ;
int i , m = src . rows , n = src . cols ;
int i , m = src . rows , n = src . cols ;
cv : : AutoBuffer < uchar > _buf ( std : : max ( m * 2 * sizeof ( floa t) + ( m * 3 + 1 ) * sizeof ( int ) , n * 2 * sizeof ( float ) ) ) ;
cv : : AutoBuffer < uchar > _buf ( std : : max ( m * 2 * sizeof ( in t) + ( m * 3 + 1 ) * sizeof ( int ) , n * 2 * sizeof ( float ) ) ) ;
// stage 1: compute 1d distance transform of each column
// stage 1: compute 1d distance transform of each column
floa t* sqr_tab = ( floa t* ) _buf . data ( ) ;
in t* sqr_tab = ( in t* ) _buf . data ( ) ;
int * sat_tab = cv : : alignPtr ( ( int * ) ( sqr_tab + m * 2 ) , sizeof ( int ) ) ;
int * sat_tab = cv : : alignPtr ( ( int * ) ( sqr_tab + m * 2 ) , sizeof ( int ) ) ;
int shift = m * 2 ;
int shift = m * 2 ;
for ( i = 0 ; i < m ; i + + )
for ( i = 0 ; i < m ; i + + )
sqr_tab [ i ] = ( float ) ( i * i ) ;
sqr_tab [ i ] = i * i ;
for ( i = m ; i < m * 2 ; i + + )
for ( i = m ; i < m * 2 ; i + + )
sqr_tab [ i ] = inf ;
sqr_tab [ i ] = inf ;
for ( i = 0 ; i < shift ; i + + )
for ( i = 0 ; i < shift ; i + + )
@ -584,13 +584,14 @@ trueDistTrans( const Mat& src, Mat& dst )
cv : : parallel_for_ ( cv : : Range ( 0 , n ) , cv : : DTColumnInvoker ( & src , & dst , sat_tab , sqr_tab ) , src . total ( ) / ( double ) ( 1 < < 16 ) ) ;
cv : : parallel_for_ ( cv : : Range ( 0 , n ) , cv : : DTColumnInvoker ( & src , & dst , sat_tab , sqr_tab ) , src . total ( ) / ( double ) ( 1 < < 16 ) ) ;
// stage 2: compute modified distance transform for each row
// stage 2: compute modified distance transform for each row
float * inv_tab = sqr_tab + n ;
float * inv_tab = ( float * ) sqr_tab + n ;
inv_tab [ 0 ] = sqr_tab [ 0 ] = 0.f ;
inv_tab [ 0 ] = 0.f ;
sqr_tab [ 0 ] = 0 ;
for ( i = 1 ; i < n ; i + + )
for ( i = 1 ; i < n ; i + + )
{
{
inv_tab [ i ] = ( float ) ( 0.5 / i ) ;
inv_tab [ i ] = ( float ) ( 0.5 / i ) ;
sqr_tab [ i ] = ( float ) ( i * i ) ;
sqr_tab [ i ] = i * i ;
}
}
cv : : parallel_for_ ( cv : : Range ( 0 , m ) , cv : : DTRowInvoker ( & dst , sqr_tab , inv_tab ) ) ;
cv : : parallel_for_ ( cv : : Range ( 0 , m ) , cv : : DTRowInvoker ( & dst , sqr_tab , inv_tab ) ) ;
@ -750,7 +751,9 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe
CV_IPP_CHECK ( )
CV_IPP_CHECK ( )
{
{
# if IPP_DISABLE_PERF_TRUE_DIST_MT
# if IPP_DISABLE_PERF_TRUE_DIST_MT
if ( cv : : getNumThreads ( ) < = 1 | | ( src . total ( ) < ( int ) ( 1 < < 14 ) ) )
// IPP uses floats, but 4097 cannot be squared into a float
if ( ( cv : : getNumThreads ( ) < = 1 | | ( src . total ( ) < ( int ) ( 1 < < 14 ) ) ) & &
src . rows < 4097 & & src . cols < 4097 )
# endif
# endif
{
{
IppStatus status ;
IppStatus status ;