Skip to content

[WIP] Split confulent lesions scil_labels_from_mask#1308

Open
zinelya wants to merge 11 commits into
scilus:masterfrom
zinelya:connectivity_labels_from_mask
Open

[WIP] Split confulent lesions scil_labels_from_mask#1308
zinelya wants to merge 11 commits into
scilus:masterfrom
zinelya:connectivity_labels_from_mask

Conversation

@zinelya
Copy link
Copy Markdown
Contributor

@zinelya zinelya commented Feb 11, 2026

Quick description

This PR introduces a new optional parameter --min_distance to the scil_labels_from_mask script. This feature allows the user to split "confluent" lesions—multiple lesions that have merged into a single connected component—using the Watershed algorithm.

Type of change

Check the relevant options.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Provide data, screenshots, command line to test (if relevant)

mask.nii.gz
default_labels.nii.gz
min_dist_labels.nii.gz

image

Checklist

  • My code follows the style guidelines of this project (run autopep8)
  • I added relevant citations to scripts, modules and functions docstrings and descriptions
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I moved all functions from the script file (except the argparser and main) to scilpy modules
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 11, 2026

Codecov Report

❌ Patch coverage is 58.73016% with 156 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.57%. Comparing base (7146797) to head (e577c4a).
⚠️ Report is 53 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1308      +/-   ##
==========================================
- Coverage   72.65%   72.57%   -0.08%     
==========================================
  Files         295      297       +2     
  Lines       25603    25898     +295     
  Branches     3607     3645      +38     
==========================================
+ Hits        18602    18796     +194     
- Misses       5487     5572      +85     
- Partials     1514     1530      +16     
Flag Coverage Δ
smoketests 69.75% <58.73%> (-0.05%) ⬇️
unittests 14.08% <2.38%> (-0.15%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Scripts 75.09% <69.95%> (-0.10%) ⬇️
Library 69.56% <44.24%> (-0.07%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/scilpy/cli/scil_labels_from_mask.py Outdated
p.add_argument('--min_volume', type=float, default=7,
help='Minimum volume in mm3 [%(default)s],'
'Useful for lesions.')
p.add_argument('--min_distance', type=int, default=None,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this will allow you to do what you want here:
p.add_argument('--watershed', metavar='MIN_DISTANCE', type=int, nargs='?', const=1, help='Use a watershed algorithm, if provided the parameter (default: 1 voxel) allow to ...')

This make so p.watershed is None by default, if you use --watershep it is 1 by default, but you can do --watershed 10 to change it.

min_voxel_count: int, optional
Minimum number of voxels for a blob to be considered. Blobs with fewer
voxels will be ignored.
min_distance : int, optional
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it should be explicit in the docstring that this trigger a change to a watershed algorithm

label_map = watershed(-distance, markers, mask=mask_data)
nb_structures = np.max(label_map)
else:
label_map, nb_structures = ndi.label(mask_data)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe a small comment saying "Any contigous regions touching even by a single voxel will be considered a single label"

Comment thread src/scilpy/image/labels.py Outdated

def get_labels_from_mask(mask_data, labels=None, background_label=0,
min_voxel_count=0):
min_voxel_count=0, min_distance=0):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It would be clearer if it was None and if your condition was if min_distance is not None: later

@ThoumyreStanislas
Copy link
Copy Markdown
Contributor

Very cool extension, it works very well for me, but there are some ( small) lesions for which segmentation is a bit messy, and I don't know how to adjust the minimum distance to compensate for this. I'm having a little trouble understanding how the minimum distance system works in the algorithm. Perhaps it needs to be a little more verbose in the min distance parameter. For the code, I have nothing to add at this point other than François' comments.

@zinelya
Copy link
Copy Markdown
Contributor Author

zinelya commented Mar 24, 2026

Very cool extension, it works very well for me, but there are some ( small) lesions for which segmentation is a bit messy, and I don't know how to adjust the minimum distance to compensate for this. I'm having a little trouble understanding how the minimum distance system works in the algorithm. Perhaps it needs to be a little more verbose in the min distance parameter. For the code, I have nothing to add at this point other than François' comments.

Thank you for testing it! :)
I have updated the documentation hoping it will help. There is no trick for choosing the best min_distance (you will need to tailor it to your data).

One recommended workflow:
run scil_labels_from_mask first without --watershed to get an initial labeling,
then use scil_labels_split_volume_by_ids to isolate individual blobs.
You can then identify which blobs look confluent and re-run scil_labels_from_mask on each one individually with --watershed, adjusting min_distance as needed per blob.

@frheault frheault enabled auto-merge March 27, 2026 18:46
Copy link
Copy Markdown
Contributor

@arnaudbore arnaudbore left a comment

Choose a reason for hiding this comment

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

Add a test with your new param and GTG

auto-merge was automatically disabled April 17, 2026 16:29

Head branch was pushed to by a user without write access

@arnaudbore arnaudbore changed the title Split confulent lesions scil_labels_from_mask [WIP] Split confulent lesions scil_labels_from_mask May 7, 2026
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.

4 participants