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

Ensure watershed auto-markers respect mask #3809

Merged
merged 8 commits into from
Mar 30, 2019

Conversation

jni
Copy link
Member

@jni jni commented Mar 19, 2019

Description

Fixes #3808

Additionally, I took the opportunity to allow watershed without passing in markers. Then the local minima in the image are used.

Checklist

For reviewers

  • Check that the PR title is short, concise, and will make sense 1 year
    later.
  • Check that new functions are imported in corresponding __init__.py.
  • Check that new features, API changes, and deprecations are mentioned in
    doc/release/release_dev.rst.
  • Consider backporting the PR with @meeseeksdev backport to v0.14.x

@pep8speaks
Copy link

pep8speaks commented Mar 19, 2019

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

Line 82:50: W504 line break after binary operator

Line 55:80: E501 line too long (98 > 79 characters)
Line 56:80: E501 line too long (98 > 79 characters)
Line 57:80: E501 line too long (98 > 79 characters)
Line 58:80: E501 line too long (98 > 79 characters)
Line 59:80: E501 line too long (98 > 79 characters)
Line 60:43: E241 multiple spaces after ','
Line 60:48: E241 multiple spaces after ','
Line 60:53: E241 multiple spaces after ','
Line 60:58: E241 multiple spaces after ','
Line 60:63: E241 multiple spaces after ','
Line 60:68: E241 multiple spaces after ','
Line 60:80: E501 line too long (98 > 79 characters)
Line 61:43: E241 multiple spaces after ','
Line 61:48: E241 multiple spaces after ','
Line 61:53: E241 multiple spaces after ','
Line 61:58: E241 multiple spaces after ','
Line 61:63: E241 multiple spaces after ','
Line 61:68: E241 multiple spaces after ','
Line 61:80: E501 line too long (98 > 79 characters)
Line 62:48: E241 multiple spaces after ','
Line 62:53: E241 multiple spaces after ','
Line 62:58: E241 multiple spaces after ','
Line 62:63: E241 multiple spaces after ','
Line 62:80: E501 line too long (98 > 79 characters)
Line 63:53: E241 multiple spaces after ','
Line 63:58: E241 multiple spaces after ','
Line 63:80: E501 line too long (98 > 79 characters)
Line 64:53: E241 multiple spaces after ','
Line 64:58: E241 multiple spaces after ','
Line 64:80: E501 line too long (98 > 79 characters)
Line 65:80: E501 line too long (98 > 79 characters)
Line 66:53: E241 multiple spaces after ','
Line 66:58: E241 multiple spaces after ','
Line 66:80: E501 line too long (98 > 79 characters)
Line 67:53: E241 multiple spaces after ','
Line 67:58: E241 multiple spaces after ','
Line 67:80: E501 line too long (98 > 79 characters)
Line 68:48: E241 multiple spaces after ','
Line 68:53: E241 multiple spaces after ','
Line 68:58: E241 multiple spaces after ','
Line 68:63: E241 multiple spaces after ','
Line 68:80: E501 line too long (98 > 79 characters)
Line 69:43: E241 multiple spaces after ','
Line 69:48: E241 multiple spaces after ','
Line 69:53: E241 multiple spaces after ','
Line 69:58: E241 multiple spaces after ','
Line 69:63: E241 multiple spaces after ','
Line 69:68: E241 multiple spaces after ','
Line 69:80: E501 line too long (98 > 79 characters)
Line 70:43: E241 multiple spaces after ','
Line 70:48: E241 multiple spaces after ','
Line 70:53: E241 multiple spaces after ','
Line 70:58: E241 multiple spaces after ','
Line 70:63: E241 multiple spaces after ','
Line 70:68: E241 multiple spaces after ','
Line 70:80: E501 line too long (98 > 79 characters)
Line 71:80: E501 line too long (98 > 79 characters)
Line 72:80: E501 line too long (98 > 79 characters)
Line 73:80: E501 line too long (98 > 79 characters)
Line 74:80: E501 line too long (98 > 79 characters)
Line 75:80: E501 line too long (99 > 79 characters)

Comment last updated at 2019-03-26 12:26:38 UTC

Copy link
Member

@lagru lagru left a comment

Choose a reason for hiding this comment

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

Only some small comments / questions. Using local minima as seed points in case of None is nice new feature!

"`image` (shape {})".format(mask.shape, image.shape))
raise ValueError(message)
if markers is None:
from .extrema import local_minima
Copy link
Member

@lagru lagru Mar 21, 2019

Choose a reason for hiding this comment

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

What's the reasoning for making this a lazy import?

Copy link
Member Author

Choose a reason for hiding this comment

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

extrema imports from watershed (the offsets to raveled neighbors), so not using this resulted in a circular import. I guess the correct way is to move offsets to its own utility file.

from .extrema import local_minima
markers_bool = local_minima(image, connectivity=connectivity) * mask
markers = ndi.label(markers_bool)[0]
elif not isinstance(markers, (np.ndarray, list, tuple)):
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if I missed something but wouldn't it be more readable to remove the not and switch the bodies of this elif- and the following else-statements? Maybe even test for "int-ness" and add a third branch that raises a nice TypeError if markers has an unsupported type?

Copy link
Member Author

@jni jni Mar 26, 2019

Choose a reason for hiding this comment

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

Possibly this is true, I'm not sure about the original rationale, this is not new code. I'll change it.

The desired number of markers, or an array marking the basins with the
values to be assigned in the label matrix. Zero means not a marker.
values to be assigned in the label matrix. Zero means not a marker. If
no markers are given, the local minima of the image are used as
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: I think "no markers" may be confused with giving 0 or passing in an array that is False everywhere.

Suggested change
no markers are given, the local minima of the image are used as
no ``None``, the local minima of the image are used as

Maybe remove "Zero means not a marker." and just display a warning if the input leads to no seeds being defined. Is there a use case where this doesn't hint at a usage error?

Copy link
Member

Choose a reason for hiding this comment

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

If None (no markers provided), the local minimal of the image...

data = blob
mask = (data != 255)
out = watershed(data, 25, connectivity=2, mask=mask)
# There should be no markers where the mask is false
Copy link
Member

Choose a reason for hiding this comment

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

Why do you call this markers? For me markers and seeds are synonyms, corresponding to marked pixels from which the watershed flooding is done. How about "labeled pixels"? Sorry to be nitpicking about a comment in a test ;-).

Copy link
Member

Choose a reason for hiding this comment

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

OK, I think I got it, we're talking about the same thing for markers, you just want to check that no marker was chosen outside the mask, so that all pixels outside the mask in the segmentation are set to zero. OK!

@emmanuelle
Copy link
Member

The code looks fine to me. Just a question, why did you use local_minimal and not peak_local_max? With peak_local_max it would be possible to add a minimal distance between local minima, but then it adds another parameter... Well, I guess the watershed only provides good results with well-chosen markers anyway.

@jni
Copy link
Member Author

jni commented Mar 26, 2019

@emmanuelle we've had a lot of issues with peak_local_max being buggy or having strange behaviour, many of which are unresolved, see:

https://github.com/scikit-image/scikit-image/issues?utf8=✓&q=is%3Aissue+is%3Aopen+peak_local_max

So I much prefer using local_minima, which actually matches the original watershed paper anyway. I'm less interested in making the watershed function do all possible seeding strategies than in providing seedless watershed as originally proposed.

@jni
Copy link
Member Author

jni commented Mar 26, 2019

@lagru @emmanuelle I believe I have addressed your concerns. =)

@jni
Copy link
Member Author

jni commented Mar 27, 2019

Hmm, failure in Py3.7 that seems unrelated to this PR:

Warning, treated as error:
/home/travis/build/scikit-image/scikit-image/doc/source/auto_examples/color_exposure/plot_rgb_to_hsv.rst:26:Explicit markup ends without a blank line; unexpected unindent.

I'll see if I can fix it.

@emmanuelle
Copy link
Member

Merging, thanks!

@emmanuelle emmanuelle merged commit 8f733a4 into scikit-image:master Mar 30, 2019
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.

None yet

4 participants