Skip to content

Add edema and swim bladder segmentation and align the model presets with the webapp - #5

Merged
MarkDanielArndt merged 12 commits into
MarkDanielArndt:mainfrom
JonaRichter:feature/webapp-parity-edema-swimbladder
Jul 30, 2026
Merged

Add edema and swim bladder segmentation and align the model presets with the webapp#5
MarkDanielArndt merged 12 commits into
MarkDanielArndt:mainfrom
JonaRichter:feature/webapp-parity-edema-swimbladder

Conversation

@JonaRichter

Copy link
Copy Markdown
Contributor

Summary

Brings the extension's segmentation options in line with the reference webapp: edema and swim bladder segmentation, the three model presets the webapp actually offers, and the current model weights.

Depends on #4. Both branches target main, so until #4 merges the commit list here also contains its five commits. The six commits above 8dc98e1 are the ones belonging to this change; the diff shrinks to those on its own once #4 lands.

What is in here

Edema segmentation — manifest entry, checkbox, subprocess plumbing, an Edema segment in the MRML scene with an EdemaArea_um2 column, an overlay colour, and Excel/CSV export.

Swim bladder segmentation — the same end-to-end wiring, plus two things it does not share with the other roles. It uses FPN rather than Unet, so the model loader gained a model_type parameter; and its measurements come from compute_tube_metrics(), ported near-verbatim from the webapp, which fits a minimum-area rotated rectangle so the reported width is the tube's cross-section regardless of how it sits in the frame.

Three presets instead of twoFast & Easy (256 px), Complex & Slower (512 px) and Fine-tuned DESY, named exactly as the webapp names them. Input resolution is now per preset rather than a single global default.

Current model weights — the general and DESY body/eye entries still pointed at 256px-era files that the webapp had already replaced with 512px ones. All refreshed, with checksums and revisions computed from the actual downloaded files rather than copied.

Two things that were wrong on the way here

Edema is not DESY-only. The work started from the assumption that the webapp offers edema only on its DESY preset, because the preset table lists None for the others. The comment directly above that table reads "None for eye/edema/swimbladder filenames means use the pipeline default"None selects the default file, it does not disable the feature, and the call site confirms it by passing an empty kwargs dict.

best_model_body_3400_vgg19.pth is not a legacy file. It was initially replaced as stale during the weight refresh. It is the webapp's current Fast & Easy preset — the only one running at 256px, which matters for anyone without a fast local GPU, where 512px inference is noticeably slower.

Both were caught by checking the live Hugging Face Space against the webapp's own repository; the two sources are byte-identical for app.py and seg.py.

One deliberate deviation from the webapp

Edema is offered on Fast & Easy and DESY, but not on Complex & Slower, where the checkbox greys out with a hint naming the presets that do offer it.

The model repository has a 256px edema model and a 512px DESY one, but no 512px general counterpart. The webapp fills that gap by falling back to the 256px model and feeding it 512px input. That runs without error and produces a plausible-looking number, which is the failure mode worth avoiding — a wrong measurement is worse than an unavailable one. The rule is now "offer the role where a resolution-matched model exists"; if a 512px general edema model appears, wiring it in re-enables the checkbox with no other change.

An inconsistent request — for example a scene saved while the role was still offered — raises an actionable error rather than a bare KeyError or a silently empty column.

Verification

pytest tests/ — 594 passed.

Beyond the wiring, the tests pin the two mistakes that are invisible at runtime: an FPN checkpoint loaded into a Unet, and a 512px-trained net fed 256px input, both complete without raising and simply produce meaningless masks. A parametrised test asserts each preset reaches the segmentation pipeline with both its own resolution and its own architecture. Another fails on any manifest entry reachable from no preset — the shape that let the edema entry be mistaken for dead weight in the first place.

Manually verified in Slicer across the presets, including the new segments appearing in the Segment Editor and surviving a scene save and reload.

Also refreshes general/DESY body and eye models to the webapp's current
512px checkpoints (issue #109), found while verifying model provenance
for this feature.
Corrects an oversight in the earlier body/eye model refresh (#109):
best_model_body_3400_vgg19.pth was mistaken for a stale legacy file
and simply replaced, when it is actually the webapp's own current,
still-offered Fast & Easy preset — the only one that runs at 256px
instead of 512px, useful for users without a fast local GPU.
The webapp's preset table lists None for some eye/edema/swim bladder
filenames, which means "use the pipeline default" — not "unavailable".
Reading it as the latter wrongly gated edema to DESY and stripped
Fast & Easy down to body-only.

All three presets now carry all five roles, differing only in weights,
input resolution and — for Fast & Easy's swim bladder — architecture
(Unet + vgg16 instead of FPN + vgg19). Verified against both the live
Hugging Face Space and the webapp's GitHub repo, which are identical.
The combo box called the 512px preset "General Model" while the webapp
calls it "Complex & Slower" — the same preset under two names across the
two tools. Labels are now verbatim; the stable ids stay untouched
because saved scenes carry them.

Model labels in the download dialog gain the matching preset name, so it
is visible which selection pulled which file.
The model repo has a 256px edema model and a 512px DESY one, but no 512px
general counterpart. The webapp fills that gap by falling through to its
pipeline default, feeding a 256px-trained net 512px input.

Rather than reproduce that, the "general" preset drops the role: the
checkbox greys out with a hint naming the presets that do offer it, and
an inconsistent request (a scene saved while it was still offered) raises
an actionable error instead of a bare KeyError or a silently empty column.
CORE_SOURCE.md existed only on the superseded webapp-parity branch, so
this branch ported compute_tube_metrics without updating the table that
exists to keep the next manual re-sync a diff rather than an excavation.
Its length.py row even predicted this port as still outstanding.

Recovered and brought up to date: the newly ported function, the seg.py
re-sync, the model preset table the manifest mirrors, and the one
deliberate deviation from the webapp with its rollback condition.
@MarkDanielArndt
MarkDanielArndt merged commit f9c3a02 into MarkDanielArndt:main Jul 30, 2026
6 checks passed
@JonaRichter
JonaRichter deleted the feature/webapp-parity-edema-swimbladder branch July 30, 2026 08:30
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.

2 participants