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

Morphological snakes #4175

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

axarekma
Copy link

Description

This PR contains a fast marching version of morphological_chan_vese based on propagation a vector of edge pixels/voxels. It is implemented as a parallel module
skimake.segmentation.morphological_chan_vese_fm
with the same interface as the original.

Credit where credit is due: design is heavily based on the source from:

Luis Alvarez, Luis Baumela, Pablo Márquez-Neila, and Pedro Henríquez,
A Real Time Morphological Snakes Algorithm, Image Processing On Line,
2 (2012), pp. 1–7. https://doi.org/10.5201/ipol.2012.abmh-rtmsa

This version extends it to 3D and has modified boundary conditions to conform with the scipy defaults for the morphologgical operators.

Extension to the existing version:
All the boolean operators are based on level_set==1 comparison, so passing an initial mask with value \notin {0,1} removes this region from the propagation and averages.

A quick and dirty benchmark on use-cases resulted in:

=== 2d case ===
data.camera() (512, 512) 35 iterations (scikit image example)
init_ls = checkerboard_level_set(image.shape, 6)
Reference: calls: 5 elapsed: 7.772 s ms/call: 1554.4 ms
Edge propagation: calls: 5 elapsed: 0.431 s ms/call: 86.1 ms
Overhead (iterations==0)
Reference: calls: 5 elapsed: 0.001 s ms/call: 0.2 ms
Edge propagation: calls: 5 elapsed: 0.009 s ms/call: 1.8 ms

=== 3d case ===
confocal.npy (60, 120, 160) 15 iterations (from the morphsnakes repo)
init_ls = circle_level_set(image.shape, (30, 50, 80), 25)
Reference: calls: 4 elapsed: 22.310 s ms/call: 5577.6 ms
Edge propagation: calls: 5 elapsed: 0.627 s ms/call: 125.4 ms
Overhead (iterations==0)
Reference: calls: 5 elapsed: 0.009 s ms/call: 1.8 ms
Edge propagation: calls: 5 elapsed: 0.052 s ms/call: 10.4 ms

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 Sep 20, 2019

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

There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻

Comment last updated at 2019-09-20 17:23:29 UTC

@jni
Copy link
Member

jni commented Sep 21, 2019

@axarekma Thanks for this and welcome to scikit-image! 😊 I'm very excited to get Chan-Vese segmentation in 3D!

Having said that, we generally don't accept bare C code into scikit-image, because we have found it is much more difficult to maintain than Python or Cython. What little is in the repo is there for historical reasons. (And even if we did take C code, we would probably aim to avoid macros!) So, this could would need to be significantly re-worked before getting merged. Do you have the bandwidth to port the C code to Cython?

Another question I have is whether this is a pure speedup of Chan-Vese or actually a change in behaviour? If it is only a speedup (to within numerical accuracy), then I would aim to replace the existing function, rather than create a new function.

If you want to iterate to get it merged, we will be very happy to help you! My main comments are:

  • port C to Cython
  • keep array allocations etc in pure Python
  • try to keep functions short, no more than ~25 lines. If it needs to be longer, it can probably be broken up into smaller functions.

I think this is a very valuable contribution, so I would keep it open whether you have time to keep working on it or not!

@axarekma
Copy link
Author

Thanks for the comments @jni.

This is one of those methods I have been searching for some time to find a decent 3D implementation of (in vain), so I ended up writing up something in C++/pybind11 for personal use a while ago. The PR was basically a minimal edit to that package to make it compatible with scikit-image which explains the stylistic differences. The internal c++ logic is minimal, so porting it to cython should not be that big of a hassle. However, I have no idea if I have the time to do that in the near future.

For most use cases the module is a pure speedup of the python implementation.
For internal testing I used unittest.assertEqual for all the tests vs. the original version so it should be (up to whatever the default floating-point tolerance is). I kept the interface verbatim and copy-pasted the current unit-tests. As everything is fair game in python, it does lose the flexibility to override the
morphosnakes.sup_inf and morphosnakes.inf_sup with nondefault boundary conditions, if one so wishes.

  • I have to see how much time I can allocate on this
  • I think all array allocations already are through numpy (no calls to 'malloc' or 'new' except for vector in the parallel edge sweeps)
  • ok

As for the macros, I have to admit I did not do my due diligence of checking if there is noticeable overhead by switching to functions.

@rfezzani rfezzani mentioned this pull request Sep 30, 2019
9 tasks
Base automatically changed from master to main February 18, 2021 18:23
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

3 participants