-
-
Notifications
You must be signed in to change notification settings - Fork 55.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cv2.normalize with NORM_MINMAX produces small values below set minimum on float32 #26588
Comments
Any update regarding this? I'm also facing same issue. |
Not sure if useful, but this seems to work fine on Windows. |
Still produces the wrong results on arm64 macOS when using float 32. Reproducer:
Result is small negative which is wrong:
|
Confirmed reproducer triggers a problem on Windows as well. |
I was able to reproduce it in the C++ code
test_arithm.cpp(2228): error: Expected equality of these values: |
I've traced the problem to the following line
Changing the code to this:
Not rounding this yields |
The line scale = (float)scale indeed doesn't look like making sense as smin is a double and in the next line the result is rounded anyway. |
Added a small PR for this: |
I've created some code to find the smallest fit within the boundaries. It appears tests are failing because it expects:
expect_max evaluates to 100, If I'm not mistaking this means it allows to be outside of the interval. I hope an active contributor with more context can pitch in and decide what is most important: |
That's too much change now and could cause the performance problems again the first try years ago caused which lead to being it reverted. What about just clamping the result to the min value if it exceeds it? I.e. just adding something like this after shift = dmin - smin*scale; if (shift < dmin) |
Ah I see the problem, the actual calculation is done in convertTo and not in the function where the current changes apply. Then the performance change risk is low. |
System Information
OpenCV python version: 4.10.0
Operating System / Platform: macOS 15.1.1 arm64 M2
Python version: 3.9.6 (/usr/bin/python3 provided by macOS)
Detailed description
The following code shows unexpected small negative numbers when trying to normalize an image between 0 and 1 while a comparison, which is mathematically not exactly the same, works fine. Note: The comparison img1 is keeping the offset from 0, I just used it for a quick check.
This appears to be the same as #6125 and #6170 which apparently has been fixed once in dev but then has been everted due to performance impacts.
This bug, if I don't have a misunderstanding of the OpenCV NORM_MINMAX definition, is serious as even small negative numbers can lead to critical follow up errors. For safety one can of course follow it with a img = np.clip(img, 0, 1) which is advised anyway for critical applications, but the result is mathematically slightly wrong.
If the performance impact can still be seen today with a fix, then I suggest to add at least internally a clip.
Datatype of img is np.float32. Changing to np.double like suggested in the older bug doesn't change anything.
If needed I guess I would be able to attach a reproducer input image and code.
Steps to reproduce
On arm64 macOS:
Writes wrong result, small negative min:
Issue submission checklist
The text was updated successfully, but these errors were encountered: