{
static const int DIST_SHIFT = 16;
-static const int INIT_DIST0 = (INT_MAX >> 2);
+static const int INIT_DIST0 = INT_MAX;
+static const int DIST_MAX = (INT_MAX >> 2);
#define CV_FLT_TO_FIX(x,n) cvRound((x)*(1<<(n)))
static void
{
const int BORDER = 1;
int i, j;
- const int HV_DIST = CV_FLT_TO_FIX( metrics[0], DIST_SHIFT );
- const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], DIST_SHIFT );
+ const unsigned int HV_DIST = CV_FLT_TO_FIX( metrics[0], DIST_SHIFT );
+ const unsigned int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], DIST_SHIFT );
const float scale = 1.f/(1 << DIST_SHIFT);
const uchar* src = _src.ptr();
for( i = 0; i < size.height; i++ )
{
const uchar* s = src + i*srcstep;
- int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER;
+ unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
for( j = 0; j < BORDER; j++ )
tmp[-j-1] = tmp[size.width + j] = INIT_DIST0;
tmp[j] = 0;
else
{
- int t0 = tmp[j-step-1] + DIAG_DIST;
- int t = tmp[j-step] + HV_DIST;
+ unsigned int t0 = tmp[j-step-1] + DIAG_DIST;
+ unsigned int t = tmp[j-step] + HV_DIST;
if( t0 > t ) t0 = t;
t = tmp[j-step+1] + DIAG_DIST;
if( t0 > t ) t0 = t;
for( i = size.height - 1; i >= 0; i-- )
{
float* d = (float*)(dist + i*dststep);
- int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER;
+ unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
for( j = size.width - 1; j >= 0; j-- )
{
- int t0 = tmp[j];
+ unsigned int t0 = tmp[j];
if( t0 > HV_DIST )
{
- int t = tmp[j+step+1] + DIAG_DIST;
+ unsigned int t = tmp[j+step+1] + DIAG_DIST;
if( t0 > t ) t0 = t;
t = tmp[j+step] + HV_DIST;
if( t0 > t ) t0 = t;
if( t0 > t ) t0 = t;
tmp[j] = t0;
}
+ t0 = (t0 > DIST_MAX) ? DIST_MAX : t0;
d[j] = (float)(t0 * scale);
}
}
{
const int BORDER = 2;
int i, j;
- const int HV_DIST = CV_FLT_TO_FIX( metrics[0], DIST_SHIFT );
- const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], DIST_SHIFT );
- const int LONG_DIST = CV_FLT_TO_FIX( metrics[2], DIST_SHIFT );
+ const unsigned int HV_DIST = CV_FLT_TO_FIX( metrics[0], DIST_SHIFT );
+ const unsigned int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], DIST_SHIFT );
+ const unsigned int LONG_DIST = CV_FLT_TO_FIX( metrics[2], DIST_SHIFT );
const float scale = 1.f/(1 << DIST_SHIFT);
const uchar* src = _src.ptr();
for( i = 0; i < size.height; i++ )
{
const uchar* s = src + i*srcstep;
- int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER;
+ unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
for( j = 0; j < BORDER; j++ )
tmp[-j-1] = tmp[size.width + j] = INIT_DIST0;
tmp[j] = 0;
else
{
- int t0 = tmp[j-step*2-1] + LONG_DIST;
- int t = tmp[j-step*2+1] + LONG_DIST;
+ unsigned int t0 = tmp[j-step*2-1] + LONG_DIST;
+ unsigned int t = tmp[j-step*2+1] + LONG_DIST;
if( t0 > t ) t0 = t;
t = tmp[j-step-2] + LONG_DIST;
if( t0 > t ) t0 = t;
for( i = size.height - 1; i >= 0; i-- )
{
float* d = (float*)(dist + i*dststep);
- int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER;
+ unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
for( j = size.width - 1; j >= 0; j-- )
{
- int t0 = tmp[j];
+ unsigned int t0 = tmp[j];
if( t0 > HV_DIST )
{
- int t = tmp[j+step*2+1] + LONG_DIST;
+ unsigned int t = tmp[j+step*2+1] + LONG_DIST;
if( t0 > t ) t0 = t;
t = tmp[j+step*2-1] + LONG_DIST;
if( t0 > t ) t0 = t;
if( t0 > t ) t0 = t;
tmp[j] = t0;
}
+ t0 = (t0 > DIST_MAX) ? DIST_MAX : t0;
d[j] = (float)(t0 * scale);
}
}
const int BORDER = 2;
int i, j;
- const int HV_DIST = CV_FLT_TO_FIX( metrics[0], DIST_SHIFT );
- const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], DIST_SHIFT );
- const int LONG_DIST = CV_FLT_TO_FIX( metrics[2], DIST_SHIFT );
+ const unsigned int HV_DIST = CV_FLT_TO_FIX( metrics[0], DIST_SHIFT );
+ const unsigned int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], DIST_SHIFT );
+ const unsigned int LONG_DIST = CV_FLT_TO_FIX( metrics[2], DIST_SHIFT );
const float scale = 1.f/(1 << DIST_SHIFT);
const uchar* src = _src.ptr();
for( i = 0; i < size.height; i++ )
{
const uchar* s = src + i*srcstep;
- int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER;
+ unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
int* lls = (int*)(labels + i*lstep);
for( j = 0; j < BORDER; j++ )
}
else
{
- int t0 = INIT_DIST0, t;
+ unsigned int t0 = INIT_DIST0, t;
int l0 = 0;
t = tmp[j-step*2-1] + LONG_DIST;
for( i = size.height - 1; i >= 0; i-- )
{
float* d = (float*)(dist + i*dststep);
- int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER;
+ unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
int* lls = (int*)(labels + i*lstep);
for( j = size.width - 1; j >= 0; j-- )
{
- int t0 = tmp[j];
+ unsigned int t0 = tmp[j];
int l0 = lls[j];
if( t0 > HV_DIST )
{
- int t = tmp[j+step*2+1] + LONG_DIST;
+ unsigned int t = tmp[j+step*2+1] + LONG_DIST;
if( t0 > t )
{
t0 = t;
tmp[j] = t0;
lls[j] = l0;
}
+ t0 = (t0 > DIST_MAX) ? DIST_MAX : t0;
d[j] = (float)(t0 * scale);
}
}
TEST(Imgproc_DistanceTransform, accuracy) { CV_DisTransTest test; test.safe_run(); }
+BIGDATA_TEST(Imgproc_DistanceTransform, large_image_12218)
+{
+ const int lls_maxcnt = 79992000; // labels's maximum count
+ const int lls_mincnt = 1; // labels's minimum count
+ int i, j, nz;
+ Mat src(8000, 20000, CV_8UC1), dst, labels;
+ for( i = 0; i < src.rows; i++ )
+ for( j = 0; j < src.cols; j++ )
+ src.at<uchar>(i, j) = (j > (src.cols / 2)) ? 0 : 255;
+
+ distanceTransform(src, dst, labels, cv::DIST_L2, cv::DIST_MASK_3, DIST_LABEL_PIXEL);
+
+ double scale = (double)lls_mincnt / (double)lls_maxcnt;
+ labels.convertTo(labels, CV_32SC1, scale);
+ Size size = labels.size();
+ nz = cv::countNonZero(labels);
+ EXPECT_EQ(nz, (size.height*size.width / 2));
+}
+
}} // namespace