-
-
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
Add compact watershed and clean up existing watershed #2211
Conversation
Nice results @jni ! A quick comment. How this example looks like with the compact watershed? http://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html#sphx-glr-auto-examples-segmentation-plot-watershed-py Also, is it necessary to make two different examples on watershed in the gallery instead of improving the existing one? I'm afraid that the multiplication of examples on same/similar functions will increase the entropy and the likelihood to find the right example. |
@sciunto compact watershed will do worse in the above example, unfortunately (it will cause the smaller object to "leak" into the bigger one). So I think it's best to leave it as a separate example... |
@scikit-image/core anyone up for reviewing this? |
👍 from me, esp for the cleanup. A lot of that was long overdue. The compact watershed is optional which gives people the choice whether or not to use it and IMHO, it is a great idea, especially for blobby objects. Another possibility would be to sort by pixel intensity and then distance in the heap code, instead of conflating the pixel value as a combination of pixel intensity and distance, but as it stands, you have a dial to tweak to offset the weighting of distance in your segmentation rather than having a tiebreaker and pragmatically, that's probably better. So, if you need my blessing, here it is and thanks for improving the code. |
The *compact* watershed transform remedies this by favoring seeds that are | ||
close to the pixel being considered. | ||
|
||
Both are implemented in the :py:func:`skimage.morphology.watershed` function. |
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.
Both what I am wondering while reading? Maybe change to "Both algorithms..."
Since the compact watershed is very similar to SLIC, why not do some cross-referencing with the |
Thanks! =D Actually the purpose of pinging you was more in case you wanted to incorporate it into CellProfiler (though I realise that's not your primary concern anymore).
Capital idea! As I was writing it I had a feeling that it wouldn't be too much trouble computing the geodesic, but I didn't realise just how trivial it would be. @ahojnnes thanks for the review, working on it! =) |
Current coverage is 90.75% (diff: 84.50%)@@ master #2211 diff @@
==========================================
Files 303 303
Lines 21849 21797 -52
Methods 0 0
Messages 0 0
Branches 2019 2002 -17
==========================================
- Hits 19817 19782 -35
+ Misses 1670 1657 -13
+ Partials 362 358 -4
|
@kevin-keraudren so I feel like I need an additional float accumulator for the geodesic, containing the distance travelled thus far. This can be reconstructed from the difference between the current element's value and the image value at that location — but only if euclidean compactness is turned off. (With it on, you still can do it, but it's just a mess.) I'm wondering whether I should leave this for another PR... Or maybe I'm just missing something? |
@jni In the case of the normal watershed, we initialise the seeds with new_elem.value = image[index]
if compactness > 0:
new_elem.value += (compactness *
_euclid_dist(index, elem.source, strides)) In the case of the geodesic watershed, there is no need for another accumulator, instead we initialise the seeds with new_elem.value = elem.value + sqrt((gradient_cost*(image[index] - image[elem.index])**2 +
euclidean_cost * _euclid_dist(index, elem.index, strides)**2)) So it requires more code changes than I first suggested, and either we are in normal watershed/compact watershed mode, or we are in geodesic watershed mode, but we should not have compact-geodesic-watershed mode! |
@kevin-keraudren I think I'll leave the geodesic for another time then. I think it would actually make a lot of sense for multichannel images, too (instead of having to compute the gradient beforehand). @ahojnnes @sciunto @soupault this is ready for another round of review, I think! |
@@ -55,6 +153,9 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None): | |||
mask: ndarray of bools or 0s and 1s, optional | |||
Array of same shape as `image`. Only points at which mask == True | |||
will be labeled. | |||
compactness : float, optional | |||
Use compact watershed [3]_ with given compactness parameter. | |||
This results in more regularly-shaped watershed basins. |
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.
A larger or smaller value? This is ambiguous to me...
LGTM, apart from Travis... |
Build succeeds locally after latest (blind) fix... @stefanv @blink1073 any ideas on how to troubleshoot this Sphinx error?
|
This is used in computing the Euclidean distance between raveled | ||
indices. | ||
compactness : float | ||
A value >0 implements the compact watershed algorithm (see .py file). |
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.
space after > sign?
Remove test of _slow_watershed
This makes compact watershed substantially simpler to use.
@sciunto, I've rebased on top of current master, which has a single-threaded sphinx build. No code has changed so I suggest merging if Travis is happy. =) |
I'll point out that Travis has passed (\o/) except for the Xcode bit which hasn't started (won't start?). |
OK, I restarted travis and now, it passes. I'm also +1, so I merge. Thanks @jni It's a very nice piece of work. |
Cleaned up the watershed code, which had lots of legacy code buried in there. Then on that nice frame I hung the new compact watershed algorithm, which gives much nicer results even for puny values of compactness.
Checklist
./doc/examples
(new features only)Gallery example to follow... Update: it's here! See output below.