未验证 提交 c4c2e2e7 编写于 作者: D Dmitry Kurtaev 提交者: GitHub

Merge pull request #24214 from dkurt:distanceTransform_big_step

Fix distanceTransform for inputs with large step and height #24214

### Pull Request Readiness Checklist

resolves https://github.com/opencv/opencv/issues/23895

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
上级 21fb10c6
......@@ -78,7 +78,7 @@ distanceTransform_3x3( const Mat& _src, Mat& _temp, Mat& _dist, const float* met
const uchar* src = _src.ptr();
int* temp = _temp.ptr<int>();
float* dist = _dist.ptr<float>();
float* dist = _dist.ptr<float>(_dist.rows - 1);
int srcstep = (int)(_src.step/sizeof(src[0]));
int step = (int)(_temp.step/sizeof(temp[0]));
int dststep = (int)(_dist.step/sizeof(dist[0]));
......@@ -87,11 +87,10 @@ distanceTransform_3x3( const Mat& _src, Mat& _temp, Mat& _dist, const float* met
initTopBottom( _temp, BORDER );
// forward pass
unsigned int* tmp = (unsigned int*)(temp + BORDER*step) + BORDER;
const uchar* s = src;
for( i = 0; i < size.height; i++ )
{
const uchar* s = src + i*srcstep;
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;
......@@ -111,13 +110,15 @@ distanceTransform_3x3( const Mat& _src, Mat& _temp, Mat& _dist, const float* met
tmp[j] = t0;
}
}
tmp += step;
s += srcstep;
}
// backward pass
float* d = (float*)dist;
for( i = size.height - 1; i >= 0; i-- )
{
float* d = (float*)(dist + i*dststep);
unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
tmp -= step;
for( j = size.width - 1; j >= 0; j-- )
{
......@@ -137,6 +138,7 @@ distanceTransform_3x3( const Mat& _src, Mat& _temp, Mat& _dist, const float* met
t0 = (t0 > DIST_MAX) ? DIST_MAX : t0;
d[j] = (float)(t0 * scale);
}
d -= dststep;
}
}
......@@ -153,7 +155,7 @@ distanceTransform_5x5( const Mat& _src, Mat& _temp, Mat& _dist, const float* met
const uchar* src = _src.ptr();
int* temp = _temp.ptr<int>();
float* dist = _dist.ptr<float>();
float* dist = _dist.ptr<float>(_dist.rows - 1);
int srcstep = (int)(_src.step/sizeof(src[0]));
int step = (int)(_temp.step/sizeof(temp[0]));
int dststep = (int)(_dist.step/sizeof(dist[0]));
......@@ -162,11 +164,10 @@ distanceTransform_5x5( const Mat& _src, Mat& _temp, Mat& _dist, const float* met
initTopBottom( _temp, BORDER );
// forward pass
unsigned int* tmp = (unsigned int*)(temp + BORDER*step) + BORDER;
const uchar* s = src;
for( i = 0; i < size.height; i++ )
{
const uchar* s = src + i*srcstep;
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;
......@@ -194,13 +195,15 @@ distanceTransform_5x5( const Mat& _src, Mat& _temp, Mat& _dist, const float* met
tmp[j] = t0;
}
}
tmp += step;
s += srcstep;
}
// backward pass
float* d = (float*)dist;
for( i = size.height - 1; i >= 0; i-- )
{
float* d = (float*)(dist + i*dststep);
unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
tmp -= step;
for( j = size.width - 1; j >= 0; j-- )
{
......@@ -228,6 +231,7 @@ distanceTransform_5x5( const Mat& _src, Mat& _temp, Mat& _dist, const float* met
t0 = (t0 > DIST_MAX) ? DIST_MAX : t0;
d[j] = (float)(t0 * scale);
}
d -= dststep;
}
}
......@@ -245,7 +249,7 @@ distanceTransformEx_5x5( const Mat& _src, Mat& _temp, Mat& _dist, Mat& _labels,
const uchar* src = _src.ptr();
int* temp = _temp.ptr<int>();
float* dist = _dist.ptr<float>();
float* dist = _dist.ptr<float>(_dist.rows - 1);
int* labels = _labels.ptr<int>();
int srcstep = (int)(_src.step/sizeof(src[0]));
int step = (int)(_temp.step/sizeof(temp[0]));
......@@ -256,12 +260,11 @@ distanceTransformEx_5x5( const Mat& _src, Mat& _temp, Mat& _dist, Mat& _labels,
initTopBottom( _temp, BORDER );
// forward pass
const uchar* s = src;
unsigned int* tmp = (unsigned int*)(temp + BORDER*step) + BORDER;
int* lls = (int*)labels;
for( i = 0; i < size.height; i++ )
{
const uchar* s = src + i*srcstep;
unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
int* lls = (int*)(labels + i*lstep);
for( j = 0; j < BORDER; j++ )
tmp[-j-1] = tmp[size.width + j] = INIT_DIST0;
......@@ -330,14 +333,17 @@ distanceTransformEx_5x5( const Mat& _src, Mat& _temp, Mat& _dist, Mat& _labels,
lls[j] = l0;
}
}
s += srcstep;
tmp += step;
lls += lstep;
}
// backward pass
float* d = (float*)dist;
for( i = size.height - 1; i >= 0; i-- )
{
float* d = (float*)(dist + i*dststep);
unsigned int* tmp = (unsigned int*)(temp + (i+BORDER)*step) + BORDER;
int* lls = (int*)(labels + i*lstep);
tmp -= step;
lls -= lstep;
for( j = size.width - 1; j >= 0; j-- )
{
......@@ -399,6 +405,7 @@ distanceTransformEx_5x5( const Mat& _src, Mat& _temp, Mat& _dist, Mat& _labels,
t0 = (t0 > DIST_MAX) ? DIST_MAX : t0;
d[j] = (float)(t0 * scale);
}
d -= dststep;
}
}
......
......@@ -344,4 +344,28 @@ TEST(Imgproc_DistanceTransform, large_square_22732)
EXPECT_EQ(0, nerrs) << "reference distance map is different from computed one at " << nerrs << " pixels\n";
}
BIGDATA_TEST(Imgproc_DistanceTransform, issue_23895_3x3)
{
Mat src = Mat::zeros(50000, 50000, CV_8U), dist;
distanceTransform(src.col(0), dist, DIST_L2, DIST_MASK_3);
int nz = countNonZero(dist);
EXPECT_EQ(nz, 0);
}
BIGDATA_TEST(Imgproc_DistanceTransform, issue_23895_5x5)
{
Mat src = Mat::zeros(50000, 50000, CV_8U), dist;
distanceTransform(src.col(0), dist, DIST_L2, DIST_MASK_5);
int nz = countNonZero(dist);
EXPECT_EQ(nz, 0);
}
BIGDATA_TEST(Imgproc_DistanceTransform, issue_23895_5x5_labels)
{
Mat src = Mat::zeros(50000, 50000, CV_8U), dist, labels;
distanceTransform(src.col(0), dist, labels, DIST_L2, DIST_MASK_5);
int nz = countNonZero(dist);
EXPECT_EQ(nz, 0);
}
}} // namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册