tiatoolbox icon indicating copy to clipboard operation
tiatoolbox copied to clipboard

:new: Define `NucleusDetector`

Open Jiaqi-Lv opened this issue 3 months ago • 2 comments

🚀 Summary

This PR introduces a new NucleusDetector engine to the TIAToolbox framework, enabling detection of nuclei from whole slide images (WSIs) or image patches using models such as MapDe and SCCNN. It supersedes PR #538 by leveraging dask for efficient, parallelized post-processing and result merging. The update also includes:


✨ Key Features

New Engine: NucleusDetector

  • Detects nuclei centroids and probabilities from WSIs or patches.
  • Produces a detection map aligned with segmentation dimensions.
  • Serializes detections into detection arrays ([[x], [y], [type], [probs]]).
  • Supports multiple output backends:
    • SQLiteStore (chunked storage for WSI/patch).
    • Dictionary (flat or patch-indexed).
    • Zarr (arrays for coordinates, classes, probabilities).
  • Compatible with nucleus detection models:
    • MapDe (implemented).
    • SCCNN (integration in progress/debugging).
  • Supports both patch-mode and WSI-mode workflows.

Technical Implementation

The detection pipeline operates as follows:

  1. Segmentation: A WSI-level segmentation map (dask array) is generated using SemanticSegmentor.infer_wsi().
  2. Parallel Post-processing: Use dask.array.map_overlap to apply the model's post-processing function across the entire segmentation map. This allows the function to execute in parallel on chunks, after which the results are automatically merged back into a unified "detection_map".
  3. Detection Map:
    • Maintains the same dimensions as the segmentation map.
    • Nuclei centroids contain the detection probability values (defaults to 1 if the model does not produce probabilities).
  4. Serialization: The "detection_map" is converted into "detection_arrays" (format: [[x], [y], [type], [probs]]) representing the detected nuclei. These records are then saved into SQLiteStore (chunk-by-chunk), zarr, or a dict (patch mode only).

Output Formats

SQLiteStore

  • WSI Mode: Returns a single SQLiteStore.
  • Patch Mode: Returns one SQLiteStore per patch.
  • Format:
    Annotation(Point(x,y), properties={'type': 'nuclei', 'probs': 0.9})
    

Dictionary

  • WSI Mode:
    {
        'x': [...],
        'y': [...],
        'classes': [...],
        'probs': [...]
    }
    
  • Patch Mode (One sub-dictionary per patch index):
    {
        0: {
            'x': [...],
            'y': [...],
            'classes': [...],
            'probs': [...]
        },
        1: { ... }
    }
    

Zarr

  • WSI Mode:
    {
        'x': [...],
        'y': [...],
        'classes': [...],
        'probs': [...]
    }
    
  • Patch Mode: Each key maps to a list of da.array objects, where each array corresponds to a patch.
    {
        'x': [[...], ...],
        'y': [[...], ...],
        'classes': [[...], ...],
        'probs': [[...], ...]
    }
    

Codebase Integration

  • Registers NucleusDetector in tiatoolbox.models and engine registry.
  • Refactors detection logic from PR #538 into modular components.
  • Updates MapDe implementation to use the new engine.
  • Begins integration of SCCNN with NucleusDetector.
  • Adds utilities for serialization into SQLite, dict, and zarr formats.
  • Introduces unit tests for detection workflows.

Tasks

  • [x] Port code from PR #538 to supersede and close it.
  • [x] Add NucleusDetector engine.
  • [x] Update existing detection models (MapDe implementation complete; SCCNN implementation in progress/debugging).
  • [x] Add unit tests.

Jiaqi-Lv avatar Nov 06 '25 17:11 Jiaqi-Lv

This PR will take over #538

shaneahmed avatar Nov 07 '25 09:11 shaneahmed

Codecov Report

:x: Patch coverage is 98.69281% with 4 lines in your changes missing coverage. Please review. :white_check_mark: Project coverage is 95.27%. Comparing base (39ae9cb) to head (7864a75).

Files with missing lines Patch % Lines
tiatoolbox/models/engine/nucleus_detector.py 97.84% 2 Missing and 2 partials :warning:
Additional details and impacted files
@@                    Coverage Diff                     @@
##           dev-define-engines-abc     #967      +/-   ##
==========================================================
+ Coverage                   95.18%   95.27%   +0.09%     
==========================================================
  Files                          77       79       +2     
  Lines                        9689     9960     +271     
  Branches                     1255     1284      +29     
==========================================================
+ Hits                         9222     9489     +267     
- Misses                        431      433       +2     
- Partials                       36       38       +2     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

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

codecov[bot] avatar Nov 23 '25 19:11 codecov[bot]