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
Fix the data scaling and clipping behavior of denoise_wavelet #3584
Fix the data scaling and clipping behavior of denoise_wavelet #3584
Conversation
Hello @grlee77! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:
Comment last updated at 2019-09-16 13:15:18 UTC |
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.
@grlee77 thanks for tackling this! I've left a few comments. I think some require discussion, perhaps at the dev meeting. =)
skimage/restoration/_denoise.py
Outdated
if multichannel: | ||
sigma = [s * scale_factor for s in sigma] | ||
else: | ||
sigma *= scale_factor |
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'm actually quite concerned that this is a major change in the behaviour of this function on identical inputs. We could classify it as a bug and just do it, but I'd like to have a discussion about it. My gut instinct is that we should have a deprecation cycle, sadly. @scikit-image/core?
As a separate issue, this function is getting pretty long and hard to read in one go. I suggest making a helper function, e.g. image, sigma = _scale_sigma_and_image_consistently(image, sigma, multichannel)
. You could even bundle in the sigma-to-list expansion.
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 agree that it may warrant that. It is clearly a change in behavior, but I think will be more intuitive going forward.
estimate_sigma
does not do any rescaling, so an input in range [0, 1e6] might produce a huge sigma value of 1e4 or so which would clearly give a crazy oversmoothing when applied to an image that has been rescaled to range [0, 1]!
For the current release, sigma
only really works if the user computed it for an image
scaled to [0, 1] or [1, -1] (or if it is left to the default of None
).
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.
Oh yes, I am absolutely not arguing that we shouldn't have the change, just whether it should be a silent/hard change or a deprecation. I think we might have many people who had their sigma set (empirically) 255 times lower than intended, and now they will find that their code does no denoising at all, and be at a loss as to why.
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 think the clip_output
flag to avoid clipping floating point outputs to [0, 1] or [-1, 1] should be applied now as a bug fix.
I think the automatic rescaling of sigma when the image must be rescaled is convenient and the right thing to do, but that could potentially go through a deprecation cycle for the reason you mention.
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.
Frustrating—so close to a bug fix, but not quite! We may argue for an accelerated deprecation in this case, perhaps; i.e., that the behavior changes immediately but that old users at least get a warning? Either that, or the more conservative option of deprecating.
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 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 would lean toward "accelerated deprecation". I think it is likely not uncommon that users with floating point data would be getting bad results currently.
My main concern with this kind of warning is that it should be easy to disable.
Is there a recommended way to do this? I am only familiar with the user needing to use with warnings.catch_warnings
context to disable the unwanted warnings?
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'm thinking some kind of long-lived keyword argument, rescale_sigma=None
, which means True
, and if set to None (default), a warning is issued, but if set to True
there is no warning. If set to False
you get the old behaviour but a warning that this option will go away in the future. In both the docstring and the warning, explain the issue and maybe link to this discussion.
Thoughts?
The point is that catch_warnings
is super-verbose and people are unlikely to want to pollute their codebase with it.
The main problem with the long-lived kwarg is that it results in yet another deprecation in the future. I don't see a better way around it though...
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.
@JDWarner tends to have opinions about these things... =)
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 think adding a rescale_sigma=None
argument sounds good and gives an easier way to bypass any warning if desired.
I messed up the scaling in the YCbCr case and still have to revisit that (see discussion above). |
This is still broken in the YCbCr case. I need to add a test case with a color image to the paramtrization |
f9c2076
to
7e25ef3
Compare
There was one CI failure in I think the primary outstanding issue is how to handle the transition to this new, more user-friendly behavior. After these changes, the user can compute |
I would really like to get this fix in for |
I'm still in favour of a deprecation pathway, but could be swayed by other voices! What's your current thinking @grlee77? |
04a5635
to
a90624f
Compare
@grlee77 as usual with sphinx errors, it's hard to tell what's wrong, but comparing your formatting with the existing ones (which work), the only thing I can spot is three spaces to indent the subsequent paragraph, rather than four. Because why not. |
Well, 3 spaces didn't seem to work either. I will try testing a bit more locally to not tie up the CI. I did check that it appeared to render okay prior to uploading the prior commit, but perhaps there was a warning I overlooked. |
@jni: Adding a There is one unrelated failure on Travis in |
82f3b51
to
512ad89
Compare
fix: remove clipping of output for floating-point inputs img_as_float no longer automatically rescales floating point inputs to [0, 1] or [-1, 1] so this clipping was no longer appropriate. TST: add unscaled floating point test case to denoise_wavelet
…tently raise a ValueError if convert2ycbcr is specified for a non-multichannel image
This default value of None is equivalent to True but will raise a DeprecationWarning Setting rescale_sigma=False restores the old behaviour (no rescaling)
adjust docstring indentation add missing backtick in denoise_wavelet docstring
512ad89
to
459813b
Compare
Updated the tests to account for the rename of |
Any objections to merging this now so it will be in 0.16? (did not want to self-merge my own PR) |
@scikit-image/core anyone around to pull the trigger? =) Clearly no objections from me, @grlee77! =) |
Tagging this as critical for the release. |
Thanks for the fix, @grlee77! |
Thanks everyone for contributing and merging! Will backport this to 0.16 (aka, I'll probably just rebase…) |
Description
This PR fixes two separate issues with data scaling in
denoise_wavelet
.The changes in Allow float->float conversion of any range #3052 (see also Code audit: usage of
img_as_float
#3373), mean that floating point inputs will no longer be automatically rescaled to the range [0, 1] or [-1, 1]. I think this is desirable, but it means that it is no longer appropriate to clip the output to this range when the input is a float.In cases where
img_as_float
does rescale the image, the same rescaling should also be applied tosigma
, but this was not previously being done. This was okay for the defaultsigma=None
as the scaling occurs prior to the internal call toestimate_sigma
.I added some test cases that check both PSNR and the output range for various dtypes. All of these test cases fail without the changes in this PR.
The previously existing tests were passing because the inputs had already been scaled via
img_as_float
prior to callingdenoise_wavelet
.Checklist
[It's fine to submit PRs which are a work in progress! But before they are merged, all PRs should provide:]
[For detailed information on these and other aspects see scikit-image contribution guidelines]
For reviewers
(Don't remove the checklist below.)
later.
__init__.py
.doc/release/release_dev.rst
.@meeseeksdev backport to v0.14.x