mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
Merge pull request #22798 from lamm45:distransform-large
Fix distransform to work with large images #22798 This attempts to fix the following bug which was caused by storing squares of large integers into 32-bit floating point variables: https://github.com/opencv/opencv/issues/22732 ### Pull Request Readiness Checklist 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. - [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
@@ -302,4 +302,46 @@ BIGDATA_TEST(Imgproc_DistanceTransform, large_image_12218)
|
||||
EXPECT_EQ(nz, (size.height*size.width / 2));
|
||||
}
|
||||
|
||||
TEST(Imgproc_DistanceTransform, wide_image_22732)
|
||||
{
|
||||
Mat src = Mat::zeros(1, 4099, CV_8U); // 4099 or larger used to be bad
|
||||
Mat dist(src.rows, src.cols, CV_32F);
|
||||
distanceTransform(src, dist, DIST_L2, DIST_MASK_PRECISE, CV_32F);
|
||||
int nz = countNonZero(dist);
|
||||
EXPECT_EQ(nz, 0);
|
||||
}
|
||||
|
||||
TEST(Imgproc_DistanceTransform, large_square_22732)
|
||||
{
|
||||
Mat src = Mat::zeros(8000, 8005, CV_8U), dist;
|
||||
distanceTransform(src, dist, DIST_L2, DIST_MASK_PRECISE, CV_32F);
|
||||
int nz = countNonZero(dist);
|
||||
EXPECT_EQ(dist.size(), src.size());
|
||||
EXPECT_EQ(dist.type(), CV_32F);
|
||||
EXPECT_EQ(nz, 0);
|
||||
|
||||
Point p0(src.cols-1, src.rows-1);
|
||||
src.setTo(1);
|
||||
src.at<uchar>(p0) = 0;
|
||||
distanceTransform(src, dist, DIST_L2, DIST_MASK_PRECISE, CV_32F);
|
||||
EXPECT_EQ(dist.size(), src.size());
|
||||
EXPECT_EQ(dist.type(), CV_32F);
|
||||
bool first = true;
|
||||
int nerrs = 0;
|
||||
for (int y = 0; y < dist.rows; y++)
|
||||
for (int x = 0; x < dist.cols; x++) {
|
||||
float d = dist.at<float>(y, x);
|
||||
double dx = (double)(x - p0.x), dy = (double)(y - p0.y);
|
||||
float d0 = (float)sqrt(dx*dx + dy*dy);
|
||||
if (std::abs(d0 - d) > 1) {
|
||||
if (first) {
|
||||
printf("y=%d, x=%d. dist_ref=%.2f, dist=%.2f\n", y, x, d0, d);
|
||||
first = false;
|
||||
}
|
||||
nerrs++;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(0, nerrs) << "reference distance map is different from computed one at " << nerrs << " pixels\n";
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
Reference in New Issue
Block a user