Skip to content

🆕 Add Cerberus#1060

Draft
measty wants to merge 101 commits into
developfrom
add-cerberus
Draft

🆕 Add Cerberus#1060
measty wants to merge 101 commits into
developfrom
add-cerberus

Conversation

@measty
Copy link
Copy Markdown
Collaborator

@measty measty commented May 8, 2026

This PR adds Cerberus model architecture and pretrained models, so it can be used within the newly-efficient tiatoolbox engines.

Still a draft as needs tidying up a bit and uploading weights to huggingface.

Example output:
image

measty and others added 30 commits January 16, 2025 13:27
- Drop Python 3.10 support
- Add Python 3.14 support
@measty measty marked this pull request as draft May 8, 2026 10:09
@shaneahmed shaneahmed changed the base branch from fix-zarr-check to develop May 8, 2026 10:11
@shaneahmed shaneahmed self-requested a review May 8, 2026 10:12
@shaneahmed shaneahmed added the enhancement New feature or request label May 8, 2026
@shaneahmed shaneahmed added this to the Release v2.1.0 milestone May 8, 2026
@shaneahmed shaneahmed changed the title Add cerberus :NEW: Add Cerberus May 8, 2026
@shaneahmed shaneahmed changed the title :NEW: Add Cerberus 🆕 Add Cerberus May 8, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 8, 2026

Codecov Report

❌ Patch coverage is 94.37387% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.63%. Comparing base (081161c) to head (6d5c595).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
tiatoolbox/models/engine/multi_task_segmentor.py 79.13% 11 Missing and 13 partials ⚠️
tiatoolbox/models/architecture/cerberus/model.py 97.69% 1 Missing and 2 partials ⚠️
...iatoolbox/models/architecture/cerberus/net_desc.py 94.91% 1 Missing and 2 partials ⚠️
tiatoolbox/annotation/utils.py 97.67% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1060      +/-   ##
===========================================
- Coverage    99.88%   99.63%   -0.25%     
===========================================
  Files           85       93       +8     
  Lines        11623    12166     +543     
  Branches      1524     1598      +74     
===========================================
+ Hits         11610    12122     +512     
- Misses           7       20      +13     
- Partials         6       24      +18     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.



class Cerberus(ModelABC, NetDesc):
"""Cerberus multi-task model for glands, lumen, nuclei, and patch class."""
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.

Can you expand the description and add some metrics reported in the paper as in the link below?
https://tia-toolbox.readthedocs.io/en/latest/_autosummary/tiatoolbox.models.architecture.kongnet.KongNet.html

Comment on lines +39 to +45
def __init__(
self,
patch_output_shape: tuple[int, int] = (144, 144),
nuclei_type_dict: dict | None = None,
gland_type_dict: dict | None = None,
lumen_type_dict: dict | None = None,
) -> None:
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces the Cerberus multi-task (gland/lumen/nuclei + patch-class) architecture and wires it into TIAToolbox’s pretrained-model registry, alongside engine improvements to support halo-based tile post-processing and some utility additions.

Changes:

  • Added Cerberus architecture (network, backbone, post-processing) + registry entry and unit tests.
  • Enhanced MultiTaskSegmentor tile-mode post-processing with an optional postproc_halo to improve boundary handling and object ownership across tiles.
  • Added an annotation-store utility (combine_annotation_stores) with tests, and improved weight-loading compatibility for checkpoints wrapped under "desc" / DataParallel prefixes.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tiatoolbox/wsicore/wsireader.py Adjusts tissue masking to neutralize pure-black pixels in thumbnails before masking.
tiatoolbox/models/models_abc.py Makes load_torch_model robust to "desc"-wrapped checkpoints and module.-prefixed keys.
tiatoolbox/models/engine/multi_task_segmentor.py Adds postproc_halo support for tile post-processing + improves tile merging/spill-to-zarr behavior.
tiatoolbox/models/engine/io_config.py Extends IO config schema/docs to carry postproc_halo.
tiatoolbox/models/architecture/cerberus/** Adds Cerberus model definition, minimal ResNet-34 encoder, decoder utilities, and post-processing.
tiatoolbox/models/__init__.py Exposes Cerberus at tiatoolbox.models.Cerberus.
tiatoolbox/data/pretrained_model.yaml Registers cerberus-resnet34 pretrained entry (HF repo + IO config).
tiatoolbox/annotation/utils.py Adds combine_annotation_stores helper.
tiatoolbox/annotation/__init__.py Re-exports combine_annotation_stores.
tests/test_annotation_utils.py Tests for combine_annotation_stores.
tests/models/test_arch_cerberus.py Unit tests for Cerberus model, postproc, and pretrained registry wiring.
tests/engines/test_multi_task_segmentor.py Tests for halo post-processing and vertical merge after Zarr spill.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1789 to +1790
# set any black pixels to white to avoid them being included in the tissue mask
thumbnail[thumbnail.sum(axis=2) == 0] = 255
Comment on lines +56 to +74
labels_ = _normalise_labels(input_path_objs, labels)
combined_store = SQLiteStore(auto_commit=False)

for source_path in input_path_objs:
source_store = SQLiteStore.open(source_path)
source_label = labels_[source_path]
annotations = []
keys = []
for key, annotation in source_store.items():
properties = dict(annotation.properties)
properties[label_property] = source_label
annotations.append(Annotation(annotation.geometry, properties))
keys.append(f"{source_label}:{key}")
if annotations:
combined_store.append_many(annotations, keys)

combined_store.commit()
combined_store.dump(output_path)
return output_path
Comment on lines +127 to +144
def _dilate_labelled_instances(inst_fg: np.ndarray, k_disk: np.ndarray) -> np.ndarray:
"""Label foreground instances, dilate each object, and fill holes."""
inst_lab = label(inst_fg)[0]
output_map = np.zeros(inst_lab.shape)
for inst_id in np.unique(inst_lab).tolist()[1:]:
inst_map = np.array(inst_lab == inst_id, dtype=np.uint8)
y1, y2, x1, x2 = get_bounding_box(inst_map)
pad = k_disk.shape[0] * 2
y1 = max(y1 - pad, 0)
x1 = max(x1 - pad, 0)
x2 = min(x2 + pad, inst_map.shape[1] - 1)
y2 = min(y2 + pad, inst_map.shape[0] - 1)
inst_map_crop = inst_map[y1:y2, x1:x2]
inst_map_crop = cv2.dilate(inst_map_crop, k_disk, iterations=1)
inst_map_crop = binary_fill_holes(inst_map_crop)
output_region = output_map[y1:y2, x1:x2]
output_region[inst_map_crop > 0] = inst_id
return output_map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants