Skip to content
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

Improved gaussian filter and convert_to_float(#5195) #5281

Merged
merged 22 commits into from
Jun 19, 2021

Conversation

michalkrawczyk
Copy link
Contributor

@michalkrawczyk michalkrawczyk commented Mar 20, 2021

Description

Propositon of fix #5195.
Since one point of problem, which is with not handling 1D array, was already resolved - This is mostly fix of normalizing in img_to_float() from int types according to Data Conversion Rules

Also changed preserve_range from filters.gaussian to True. The values in Gaussian Filter shoudn't be normalized by default - It will only give misleading results (Like in Issue #5195 itself)

For reviewers

  • Check filters.gaussian() for 1D array ( e.g np.arange(9)), especially with preserve_range=False
  • Check util.dtype.img_to_float() with some 1D, ... ,nD values
  • Check if current usages of filters.gaussian() really need preserve_range==False (Optional)

@@ -10,7 +10,7 @@


def gaussian(image, sigma=1, output=None, mode='nearest', cval=0,
multichannel=None, preserve_range=False, truncate=4.0):
multichannel=None, preserve_range=True, truncate=4.0):
Copy link
Member

Choose a reason for hiding this comment

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

When updating a function's signature, please update its docstring as well (and accordingly).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I quite didn't see point of doing that here. See part of current docstring:

preserve_range : bool, optional
    Whether to keep the original range of values. Otherwise, the input
    image is converted according to the conventions of ``img_as_float``.
    Also see
    https://scikit-image.org/docs/dev/user_guide/data_types.html

But maybe it should be rewritten to be more specific. If you consider that as necessery - I may do that

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think it is a good opportunity to rewrite it in a clearer way: "Whether to keep the original range of values. Default is True. If False, the input image is converted according to the conventions of img_as_float, i.e., renormalised based on the range of the assumed data type: https://scikit-image.org/docs/dev/user_guide/data_types.html"

skimage/util/dtype.py Outdated Show resolved Hide resolved
@pep8speaks
Copy link

pep8speaks commented Mar 23, 2021

Hello @michalkrawczyk! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

Line 20:80: E501 line too long (81 > 79 characters)
Line 36:80: E501 line too long (83 > 79 characters)
Line 52:80: E501 line too long (81 > 79 characters)

Comment last updated at 2021-06-19 21:28:59 UTC

@michalkrawczyk
Copy link
Contributor Author

A bit changed conversion at dtype since according to Direct3D most negative value should be not calculated by formula, but just changed to -1.0f. That made test to fail (Also added few more tests)

@michalkrawczyk
Copy link
Contributor Author

It seems like some test just failed because some functions are basing at gaussian with preserve_range=False.
I actually start to wonder if that usages should be rewritten to preserve_range=False or just get back to preserve_range on default set to True and leave note at documentation.

@@ -10,7 +10,7 @@


def gaussian(image, sigma=1, output=None, mode='nearest', cval=0,
multichannel=None, preserve_range=False, truncate=4.0):
multichannel=None, preserve_range=True, truncate=4.0):
Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think it is a good opportunity to rewrite it in a clearer way: "Whether to keep the original range of values. Default is True. If False, the input image is converted according to the conventions of img_as_float, i.e., renormalised based on the range of the assumed data type: https://scikit-image.org/docs/dev/user_guide/data_types.html"

skimage/filters/tests/test_gaussian.py Outdated Show resolved Hide resolved
skimage/filters/tests/test_gaussian.py Outdated Show resolved Hide resolved
skimage/filters/tests/test_gaussian.py Outdated Show resolved Hide resolved
skimage/filters/tests/test_gaussian.py Show resolved Hide resolved
skimage/filters/tests/test_gaussian.py Outdated Show resolved Hide resolved
skimage/filters/tests/test_gaussian.py Outdated Show resolved Hide resolved
skimage/filters/tests/test_gaussian.py Outdated Show resolved Hide resolved
@mkcor
Copy link
Member

mkcor commented Apr 14, 2021

Since this PR changes the default value of a function's parameter, it will affect existing code. I guess we need some kind of warning message referring to the next release version, right? @scikit-image/core

@alexdesiqueira
Copy link
Member

I guess we need some kind of warning message referring to the next release version, right?

Hi @michalkrawczyk @mkcor, please refer to our deprecation cycle policy in this case.
Thank you for your work!

michalkrawczyk and others added 7 commits April 14, 2021 18:05
Co-authored-by: Marianne Corvellec <marianne.corvellec@ens-lyon.org>
Co-authored-by: Marianne Corvellec <marianne.corvellec@ens-lyon.org>
Co-authored-by: Marianne Corvellec <marianne.corvellec@ens-lyon.org>
Co-authored-by: Marianne Corvellec <marianne.corvellec@ens-lyon.org>
@michalkrawczyk
Copy link
Contributor Author

Done. @mkcor May I ask you to have a look now?

skimage/filters/_gaussian.py Outdated Show resolved Hide resolved
michalkrawczyk and others added 3 commits April 16, 2021 16:09
Co-authored-by: Marianne Corvellec <marianne.corvellec@ens-lyon.org>
Co-authored-by: Marianne Corvellec <marianne.corvellec@ens-lyon.org>
skimage/filters/_gaussian.py Show resolved Hide resolved
skimage/filters/_gaussian.py Outdated Show resolved Hide resolved
skimage/util/dtype.py Show resolved Hide resolved
@jni
Copy link
Member

jni commented Apr 23, 2021

Hi all, sorry to jump in really late here but I don't think we should take this leap. filters.gaussian will be one of our most used functions and will now be obnoxiously noisy. Additionally, there is a question of consistency with the rest of the library — a quick search shows that all our functions use preserve_range=False, except radon_transform and non_local_means, for which we are in the middle of a deprecation to change it to False!

In short, although I do support setting preserve_range=True everywhere, it should be done as a concerted effort in the road to 1.0, not as a piecemeal, whatever is most convenient for a specific function at a specific time approach.

@michalkrawczyk
Copy link
Contributor Author

@jni Yeah I do see that actually almost all your current libraries use preserve_range=False.
The problem is that library requires more preserved_range=False while users requires more preserved_range=True and misleading results from False are more considered as bug.
It's not actually more convienient - it's more likely how gaussian filter should be in practice, without any 'additional features' by default.

@jni
Copy link
Member

jni commented Apr 23, 2021

Indeed! As I said above I think we should make the change eventually. But when we move to 1.0 we have a chance to do it without the noise. Unfortunately we can't just change the output of the function without warning as that would break many, many users' existing code.

Copy link
Contributor

@grlee77 grlee77 left a comment

Choose a reason for hiding this comment

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

I requested a minor change to use an existing decorator to handle the deprecation. Otherwise this looks good to me.

skimage/filters/_gaussian.py Outdated Show resolved Hide resolved
skimage/filters/tests/test_gaussian.py Show resolved Hide resolved
skimage/util/dtype.py Show resolved Hide resolved
@michalkrawczyk
Copy link
Contributor Author

Module cannot be found: 'skimage.restoration._inpaint' after merge with main

@grlee77
Copy link
Contributor

grlee77 commented Jun 19, 2021

Module cannot be found: 'skimage.restoration._inpaint' after merge with main

I think this is because we recently added a new Cython function for inpainting. After you merged main, you would have had to rebuild scikit-image in order to avoid this error.

I went ahead and ran this locally and fixed up some issues related to warnings in 528a88f. This is basically just either providing the preserve_range keyword or use expected_warnings to catch the deprecation warnings so that the test suite can run without raising any of these warnings.

The cosmetic changes in 0fe4242 are just for consistency with the style @rfezzani and I had been using in several other recent PRs.

Copy link
Contributor

@grlee77 grlee77 left a comment

Choose a reason for hiding this comment

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

Thanks @michalkrawczyk, this looks good to me now

@grlee77
Copy link
Contributor

grlee77 commented Jun 19, 2021

The CI errors seen here are unrelated to this PR (I saw them in a few other cases recently as well)

@alexdesiqueira
Copy link
Member

Thank you @michalkrawczyk!

@alexdesiqueira alexdesiqueira merged commit 6f431ea into scikit-image:main Jun 19, 2021
@jni
Copy link
Member

jni commented Jun 21, 2021

Hi everyone, I'm really sorry about this, but I think we should revert this. I probably should have been more explicit in my comment above: I don't think we should have this in 0.19. I think 1.0 should preserve_range=True everywhere without the keyword, and we should do that with a release-wide warning, not piecemeal warnings + kwargs everywhere. Again, the Gaussian filter is among the most used functions in scikit-image. I think it's a major mistake to force everyone using it to add a keyword argument to it that should probably be removed eventually anyway.

Since @stefanv has also expressed concerns about some of the deprecations we're making, I think we should probably have a focused meeting soon about our upcoming API choices and how we will go about making the changes.

@stefanv
Copy link
Member

stefanv commented Jun 22, 2021

Since @stefanv has also expressed concerns about some of the deprecations we're making, I think we should probably have a focused meeting soon about our upcoming API choices and how we will go about making the changes.

Thanks for bringing this up, Juan. Would you be willing to set up that meeting and write up a paragraph or two about the challenge faced to bring everyone up to speed?

@grlee77
Copy link
Contributor

grlee77 commented Jun 22, 2021

Thanks for bringing this up, Juan. Would you be willing to set up that meeting and write up a paragraph or two about the challenge faced to bring everyone up to speed?

I just opened #5439 to summarize some of the things I am aware of. Many are relatively easy to implement once we have a decision on the desired direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

filters.gaussian does not work on 1D input
7 participants