//BEGIN ATS ADDITION // 8-bit grayscale distance transform function static void distanceATS_L1_8u( const Mat& src, Mat& dst ) { int width = src.cols, height = src.rows; int a; uchar lut[256]; int x, y; const uchar *sbase = src.ptr(); uchar *dbase = dst.ptr(); int srcstep = (int)src.step; int dststep = (int)dst.step; CV_Assert( src.type() == CV_8UC1 && dst.type() == CV_8UC1 ); CV_Assert( src.size() == dst.size() ); ////////////////////// forward scan //////////////////////// for( x = 0; x < 256; x++ ) lut[x] = cv::saturate_cast<uchar>(x+1); //init first pixel to max (we're going to be skipping it) dbase[0] = (uchar)(sbase[0] == 0 ? 0 : 255); //first row (scan west only, skip first pixel) for( x = 1; x < width; x++ ) dbase[x] = (uchar)(sbase[x] == 0 ? 0 : lut[dbase[x-1]]); for( y = 1; y < height; y++ ) { sbase += srcstep; dbase += dststep; //for left edge, scan north only a = sbase[0] == 0 ? 0 : lut[dbase[-dststep]]; dbase[0] = (uchar)a; for( x = 1; x < width; x++ ) { a = sbase[x] == 0 ? 0 : lut[MIN(a, dbase[x - dststep])]; dbase[x] = (uchar)a; } } ////////////////////// backward scan /////////////////////// a = dbase[width-1]; // do last row east pixel scan here (skip bottom right pixel) for( x = width - 2; x >= 0; x-- ) { a = lut[a]; dbase[x] = (uchar)(CV_CALC_MIN_8U(a, dbase[x])); } // right edge is the only error case for( y = height - 2; y >= 0; y-- ) { dbase -= dststep; // do right edge a = lut[dbase[width-1+dststep]]; dbase[width-1] = (uchar)(MIN(a, dbase[width-1])); for( x = width - 2; x >= 0; x-- ) { int b = dbase[x+dststep]; a = lut[MIN(a, b)]; a = MIN(a, dbase[x]); dbase[x] = (uchar)(a); } } }
/* 8-bit grayscale distance transform function */ static void icvDistanceATS_L1_8u( const CvMat* src, CvMat* dst ) { int width = src->cols, height = src->rows; int a; uchar lut[256]; int x, y; const uchar *sbase = src->data.ptr; uchar *dbase = dst->data.ptr; int srcstep = src->step; int dststep = dst->step; CV_Assert( CV_IS_MASK_ARR( src ) && CV_MAT_TYPE( dst->type ) == CV_8UC1 ); CV_Assert( CV_ARE_SIZES_EQ( src, dst )); ////////////////////// forward scan //////////////////////// for( x = 0; x < 256; x++ ) lut[x] = CV_CAST_8U(x+1); //init first pixel to max (we're going to be skipping it) dbase[0] = (uchar)(sbase[0] == 0 ? 0 : 255); //first row (scan west only, skip first pixel) for( x = 1; x < width; x++ ) dbase[x] = (uchar)(sbase[x] == 0 ? 0 : lut[dbase[x-1]]); for( y = 1; y < height; y++ ) { sbase += srcstep; dbase += dststep; //for left edge, scan north only a = sbase[0] == 0 ? 0 : lut[dbase[-dststep]]; dbase[0] = (uchar)a; for( x = 1; x < width; x++ ) { a = sbase[x] == 0 ? 0 : lut[MIN(a, dbase[x - dststep])]; dbase[x] = (uchar)a; } } ////////////////////// backward scan /////////////////////// a = dbase[width-1]; // do last row east pixel scan here (skip bottom right pixel) for( x = width - 2; x >= 0; x-- ) { a = lut[a]; dbase[x] = (uchar)(CV_CALC_MIN_8U(a, dbase[x])); } // right edge is the only error case for( y = height - 2; y >= 0; y-- ) { dbase -= dststep; // do right edge a = lut[dbase[width-1+dststep]]; dbase[width-1] = (uchar)(MIN(a, dbase[width-1])); for( x = width - 2; x >= 0; x-- ) { int b = dbase[x+dststep]; a = lut[MIN(a, b)]; dbase[x] = (uchar)(MIN(a, dbase[x])); } } }