Skip to content

Fix NN resize with dimentions > 4#16497

Merged
alalek merged 4 commits intoopencv:3.4from
keeper121:master
Feb 16, 2020
Merged

Fix NN resize with dimentions > 4#16497
alalek merged 4 commits intoopencv:3.4from
keeper121:master

Conversation

@keeper121
Copy link
Copy Markdown
Contributor

@keeper121 keeper121 commented Feb 3, 2020

relates #15075

This pullrequest changes

This resolves issue #15075
Fixes NN resize image last dimension values with odd dims > 4.

force_builders=linux,docs

@asmorkalov
Copy link
Copy Markdown
Contributor

@keeper121 Thanks a lot for contribution! Could you add test for the case you've fixed?

@keeper121
Copy link
Copy Markdown
Contributor Author

@asmorkalov Hi, what format the test case should look like? This bug comes from #15075.

It has python script which do nearest neighbor resize.

import numpy as np
import cv2

# up to DIM=4 is OK
DIM = 5
T = np.zeros((12, 12,DIM)).astype(np.uint8)
T[2, 2, DIM-1] = 1
print("Sum: ", T.sum())
print(T[:, :, DIM-1])
R = cv2.resize(T, None, fx=0.9, fy=1,interpolation=cv2.INTER_NEAREST)
# it does not help to supply a pre-allocated array either
#R = np.zeros((12, 11, DIM)).astype(np.uint8)
#R = cv2.resize(T, dsize=R.shape[:2], dst=R, interpolation=cv2.INTER_NEAREST)

print("Sum: ", R.sum())
print(R[:, :, DIM-1])

Output before:

Sum:  1
[[0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]]
Sum:  836
[[248 113   0 214 176  85   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0]]

Output after fix:

Sum:  1
[[0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]]
Sum: 1
[[0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0]]

The PR fixes case when input image has odd size of channel dimension more than 4. It occurs in https://github.com/keeper121/opencv/blob/57c99914133bea42b1fd6e176ebf35e210d7163d/modules/imgproc/src/resize.cpp#L1044-L1050 where the last image's channel part is not going through the loop.

@asmorkalov
Copy link
Copy Markdown
Contributor

c++ test with the test data you posted before is enough.

@asmorkalov
Copy link
Copy Markdown
Contributor

Also you can extend existing C++ test for resize to case with 4 channels too.

@alalek
Copy link
Copy Markdown
Member

alalek commented Feb 11, 2020

extend existing C++ test for resize

Separate test is better.
(existing C++ test based on legacy code which generates unstable input data)

@keeper121
Copy link
Copy Markdown
Contributor Author

@alalek Hi, I added separate test.

I run it with:

opencv_test_imgproc --gtest_filter=Resize_NN.accuracy

output before fix

Note: Google Test filter = Resize_NN.accuracy
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Resize_NN
[ RUN      ] Resize_NN.accuracy
/media/keeper121/seagate/opencv/modules/imgproc/test/test_resize_nn.cpp:25: Failure
Expected equality of these values:
  i
    Which is: 5
  sum
    Which is: 6773
Resize NN TEST mat from 12x12x5 failed with sum 6773 should be 5
/media/keeper121/seagate/opencv/modules/imgproc/test/test_resize_nn.cpp:25: Failure
Expected equality of these values:
  i
    Which is: 7
  sum
    Which is: 30789
Resize NN TEST mat from 12x12x7 failed with sum 30789 should be 7
/media/keeper121/seagate/opencv/modules/imgproc/test/test_resize_nn.cpp:25: Failure
Expected equality of these values:
  i
    Which is: 9
  sum
    Which is: 7515
Resize NN TEST mat from 12x12x9 failed with sum 7515 should be 9
[  FAILED  ] Resize_NN.accuracy (0 ms)
[----------] 1 test from Resize_NN (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] Resize_NN.accuracy

 1 FAILED TEST

output after fix

Note: Google Test filter = Resize_NN.accuracy
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Resize_NN
[ RUN      ] Resize_NN.accuracy
[       OK ] Resize_NN.accuracy (0 ms)
[----------] 1 test from Resize_NN (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.

Should I add something else?

@asmorkalov asmorkalov added category: imgproc and removed pr: needs test New functionality requires minimal tests set labels Feb 14, 2020
@asmorkalov
Copy link
Copy Markdown
Contributor

There are build warnings on Windows:

C:\build\precommit_windows32\opencv\modules\imgproc\test\test_resize_nn.cpp(13): warning C4305: 'initializing': truncation from 'double' to 'float' [C:\build\precommit_windows32\build\modules\imgproc\opencv_test_imgproc.vcxproj]
C:\build\precommit_windows32\opencv\modules\imgproc\test\test_resize_nn.cpp(24): warning C4244: 'initializing': conversion from 'double' to 'float', possible loss of data [C:\build\precommit_windows32\build\modules\imgproc\opencv_test_imgproc.vcxproj]

Please take a look and fix.

@asmorkalov
Copy link
Copy Markdown
Contributor

@keeper121 I checked branch 3.4 and the issue is reproducible there too. Could you rebease it on top of 3.4 and we will merge the changes from 3.4 into master during regular procedure (weekly/bi-weekly).

So, please:

  • change "base" branch of this PR: master => 3.4 (use "Edit" button near PR title)
  • rebase your commits from master onto 3.4 branch. For example:
    git rebase -i --onto upstream/3.4 upstream/master
    (check list of your commits, save and quit (Esc + "wq" + Enter)
    where upstream is configured by following this GitHub guide and fetched (git fetch upstream).
  • push rebased commits into source branch of your fork (with --force option)

Note: no need to re-open PR, apply changes "inplace".

@asmorkalov asmorkalov added the pr: needs rebase Rebase patch (and squash fixup commits) on the top of target branch label Feb 14, 2020
@keeper121 keeper121 changed the base branch from master to 3.4 February 14, 2020 08:40
Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for contribution!

namespace opencv_test { namespace {

TEST(Resize_NN, accuracy)
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to create a new file.
Please put code after this resize test: https://github.com/opencv/opencv/blob/4.2.0/modules/imgproc/test/test_imgwarp.cpp#L1403-L1414

Please add issue number into test name.

Please avoid indentation in namespaces.

const int N = 10;
double scale_factor = 0.9;
int i1 = 5, j1 = 5; // position of pixel
for (int i = 2; i < N; ++i)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please test 5 channels only.
Lets avoid overcomplicated tests.

Comment on lines +23 to +25
dst = dst.reshape(1, dst.cols * dst.rows * dst.channels());
double sum = cv::sum(dst)[0];
EXPECT_EQ(i, sum) << "Resize NN TEST mat from " << cols << "x" << rows << "x" << i << " failed with sum " << sum << " should be " << i;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 lines alternative:

EXPECT_EQ(i, cvtest::norm(dst, NORM_L1)) << test.size;`

Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done! Thank you for contribution 👍

@alalek alalek merged commit d84360e into opencv:3.4 Feb 16, 2020
@alalek
Copy link
Copy Markdown
Member

alalek commented Feb 17, 2020

Fix has been reverted: #16600

Nightly failure example.

@keeper121
Copy link
Copy Markdown
Contributor Author

@alalek How can I debug it?

valgrind-3.15.0 on my Ubuntu 19.10 (g++ 7.5) is not showing any error. I'll try to fix it if it possible.

@alalek alalek mentioned this pull request Feb 20, 2020
jshiwam pushed a commit to jshiwam/opencv that referenced this pull request Feb 22, 2020
* Fix NN resize with dimentions > 4

* add test check for nn resize with channels > 4

* Change types from float to double

* Del unnecessary test file. Move nn test to test_imgwarp. Add 5 channels test only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python - cv2.resize with INTER_NEAREST return corrupted slice for channels > 4

3 participants