-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Clip output in denoise_tv_bregman #1943
base: main
Are you sure you want to change the base?
Conversation
I don't think this is the right solution, the clipping should be optional. There is nothing in the TV denoising equation that guarantees that the input range is not altered. |
Optional in the sense that there should be a parameter that would default to true. |
@@ -134,7 +134,7 @@ def denoise_tv_bregman(image, weight, max_iter=100, eps=1e-3, isotropic=True): | |||
|
|||
Returns | |||
------- | |||
u : ndarray | |||
out : ndarray | |||
Denoised image. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a reason this variable is called u. It refers to a variable in the equation further above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that's very clear... I would suggest that we keep out
or denoised
(both are used in the file) and replace u in the equation with that name. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jni Sounds good!
@ahojnnes sure, I can make it optional, but it still doesn't help me figure out why np.clip isn't doing its job in the tests! Any ideas? |
Or why there's no Travis???? =O |
@jni this is so weird... Hope Travis will reappear on your next commit with clipping being optional :-) |
@ahojnnes (pinging you because you seemed most familiar with this algorithm, correct me if wrong) so it looks like the failures are due to sometimes producing nan output for the test input. I added a (skimtest)
nuneziglesiasj@aradyne Mon Feb 22 16:23
~/projects/scikit-image/skimage/restoration/tests (denoise-clip)$ nosetests test_denoise:test_denoise_tv_bregman_approx_errors
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
(skimtest)
nuneziglesiasj@aradyne Mon Feb 22 16:24
~/projects/scikit-image/skimage/restoration/tests (denoise-clip)$ nosetests test_denoise:test_denoise_tv_bregman_approx_errors
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
(skimtest)
nuneziglesiasj@aradyne Mon Feb 22 16:24
~/projects/scikit-image/skimage/restoration/tests (denoise-clip)$ nosetests test_denoise:test_denoise_tv_bregman_approx_errors
F
======================================================================
FAIL: Ensure output is valid image when valid input image is given.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/nuneziglesiasj/anaconda/envs/skimtest/lib/python3.5/site-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/Volumes/Projects/scikit-image/skimage/restoration/tests/test_denoise.py", line 172, in test_denoise_tv_bregman_approx_errors
assert np.max(out) <= 1
AssertionError:
-------------------- >> begin captured stdout << ---------------------
nan ... ??? Any ideas? |
I will check later today.
|
Hm... there is no randomness in the algorithm. The only reason I can image is uninitialized memory, e.g., here https://github.com/jni/scikit-image/blob/denoise-clip/skimage/restoration/_denoise_cy.pyx#L173 ? |
@ahojnnes that was a good catch! But it doesn't explain it — each of those variables is later initialised before use. Unless I'm missing something... Which obviously I am... =\ |
@jni Let's finally solve this nasty issue. I think, I found the problem: there is an out of bounds access and the loop should be |
@ahojnnes 😱 😱 😱 Well-spotted! And it seems to have fixed it! |
@jni Hm. The tests still seem to fail in all environments. |
Hmm worked on my laptop. Will investigate soon, can't right now... |
@jni Gentle ping :-) |
I'm on holiday till the 5th, thought I could catch a few mins for this but now looking unlikely... Will revisit next week. |
LGTM, if the test case is fixed. |
@ahojnnes oh wow, LOL, just saw the test failure, I wonder if the out of range access was causing most of the range problems anyway! Working on this... |
@jni Ping :-) |
@ahojnnes I've had this tab open for the past few days. I'm not sure how to proceed now that the original "failure" passes... I was going to try to find another failing case, but that might be hard, so it's in the back burner... Thoughts? |
@jni how are we on this one? :) |
@alexandrejaguar thanks for the ping and all the other triaging you've been doing, it's great! Let's see how this rebase turns out... =) |
@jni glad I could help! |
@@ -111,6 +110,7 @@ def _denoise_tv_bregman(np_floats[:, :, ::1] image, np_floats weight, | |||
shape_ext = (rows2, cols2, dims) | |||
|
|||
cdef: | |||
np_floats[:, :, ::1] cu = u |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is causing the CI failures: u
is not declared and cu
is not used afterward...
Simply removing this line may solve the problem.
@jni Is this requirement (clipping |
I think it should only clip by default if the input is not floating point to make it consistent with # floating-point inputs are not rescaled, so don't clip their output.
clip_output = image.dtype.kind != 'f' If you want to have an explicit |
This is pretty simple: always clip the output of denoise_tv_bregman in order to prevent invalid output due to numerical errors. Fixes #1939. However, the tests are failing in 2.7 and 3.5. Anyone got any idea why???