From 4733a19babec760ba237b8c277bb1de664a641c1 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 19 Dec 2019 13:20:42 +0300 Subject: [PATCH] Merge pull request #16194 from alalek:fix_16192 * imgproc(test): resize(LANCZOS4) reproducer 16192 * imgproc: fix resize LANCZOS4 coefficients generation --- modules/imgproc/src/resize.cpp | 23 +++++++++++++---------- modules/imgproc/test/test_imgwarp.cpp | 13 +++++++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/modules/imgproc/src/resize.cpp b/modules/imgproc/src/resize.cpp index cc967cf..02f7881 100644 --- a/modules/imgproc/src/resize.cpp +++ b/modules/imgproc/src/resize.cpp @@ -920,20 +920,23 @@ static inline void interpolateLanczos4( float x, float* coeffs ) static const double cs[][2]= {{1, 0}, {-s45, -s45}, {0, 1}, {s45, -s45}, {-1, 0}, {s45, s45}, {0, -1}, {-s45, s45}}; - if( x < FLT_EPSILON ) - { - for( int i = 0; i < 8; i++ ) - coeffs[i] = 0; - coeffs[3] = 1; - return; - } - float sum = 0; double y0=-(x+3)*CV_PI*0.25, s0 = std::sin(y0), c0= std::cos(y0); for(int i = 0; i < 8; i++ ) { - double y = -(x+3-i)*CV_PI*0.25; - coeffs[i] = (float)((cs[i][0]*s0 + cs[i][1]*c0)/(y*y)); + float y0_ = (x+3-i); + if (fabs(y0_) >= 1e-6f) + { + double y = -y0_*CV_PI*0.25; + coeffs[i] = (float)((cs[i][0]*s0 + cs[i][1]*c0)/(y*y)); + } + else + { + // special handling for 'x' values: + // - ~0.0: 0 0 0 1 0 0 0 0 + // - ~1.0: 0 0 0 0 1 0 0 0 + coeffs[i] = 1e30f; + } sum += coeffs[i]; } diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index 400426a..232f374 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1708,6 +1708,19 @@ TEST(Resize, Area_half) } } +TEST(Resize, lanczos4_regression_16192) +{ + Size src_size(11, 17); + Size dst_size(11, 153); + Mat src(src_size, CV_8UC3, Scalar::all(128)); + Mat dst(dst_size, CV_8UC3, Scalar::all(255)); + + cv::resize(src, dst, dst_size, 0, 0, INTER_LANCZOS4); + + Mat expected(dst_size, CV_8UC3, Scalar::all(128)); + EXPECT_EQ(cvtest::norm(dst, expected, NORM_INF), 0) << dst(Rect(0,0,8,8)); +} + TEST(Imgproc_Warp, multichannel) { static const int inter_types[] = {INTER_NEAREST, INTER_AREA, INTER_CUBIC, -- 2.7.4