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

✨ NEW: Add Nucleus Detection Engine #538

Draft
wants to merge 27 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a6960f8
:sparkles: NEW: Add Nucleus Detection Engine
shaneahmed Feb 16, 2023
6c47506
:art: DEV: Improve structure of init
shaneahmed Feb 16, 2023
c902372
Merge branch 'develop' into new-cell-detection-engine
shaneahmed Feb 16, 2023
73cfe90
Merge remote-tracking branch 'origin/develop' into new-cell-detection…
shaneahmed Feb 20, 2023
584e43a
:memo: DOC: Add documentation for mapde and sccnn
shaneahmed Feb 20, 2023
46ffdae
:boom: DEV: Fix mpp for cell detection
shaneahmed Feb 20, 2023
951ea7d
Merge remote-tracking branch 'origin/develop' into new-cell-detection…
shaneahmed Feb 20, 2023
4e2ca8b
:bug: BUG: Fix bug with loading NucleusDetector
shaneahmed Feb 21, 2023
1af8140
:bug: BUG: Fix bug with loading sccnn
shaneahmed Feb 21, 2023
527444a
:bug: BUG: Fix test bug in test_patch_predictor.py
shaneahmed Feb 21, 2023
37b82f9
:white_check_mark: TST: Add test for NucleusDetector
shaneahmed Feb 21, 2023
1405fa0
:bug: TST: Set GPU
shaneahmed Feb 21, 2023
71cb5c6
:white_check_mark: TST: Add test to improve coverage
shaneahmed Feb 22, 2023
e4625c0
Merge remote-tracking branch 'origin/develop' into new-cell-detection…
shaneahmed Feb 24, 2023
61d811a
Merge branch 'develop' into new-cell-detection-engine
shaneahmed Mar 2, 2023
4a0a940
Merge branch 'develop' into new-cell-detection-engine
shaneahmed Mar 10, 2023
a6052fc
Merge branch 'develop' into new-cell-detection-engine
shaneahmed Mar 23, 2023
6368325
Merge branch 'develop' into new-cell-detection-engine
shaneahmed Apr 7, 2023
8b67d78
Merge branch 'develop' into new-cell-detection-engine
shaneahmed May 2, 2023
b11e6f0
:memo: Add example models
shaneahmed May 2, 2023
f538289
Merge branch 'develop' into new-cell-detection-engine
shaneahmed May 5, 2023
57bde23
Merge branch 'develop' into new-cell-detection-engine
shaneahmed May 12, 2023
861532d
Merge branch 'develop' into new-cell-detection-engine
shaneahmed May 31, 2023
2c3884a
:pushpin: Pin `torch` version
shaneahmed Jun 2, 2023
e670455
:pushpin: Pin `torch` version
shaneahmed Jun 2, 2023
8d92c5e
Merge branch 'develop' into new-cell-detection-engine
shaneahmed Jun 16, 2023
7989aa7
:hammer: Try cuda 11.8
shaneahmed Jun 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/pretrained.rst
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ input output configuration:
ioconfig = IOPatchPredictorConfig(
patch_input_shape=(31, 31),
stride_shape=(8, 8),
input_resolutions=[{"resolution": 0.25, "units": "mpp"}]
input_resolutions=[{"resolution": 0.5, "units": "mpp"}]
)


Expand All @@ -330,7 +330,7 @@ input output configuration:
ioconfig = IOPatchPredictorConfig(
patch_input_shape=(252, 252),
stride_shape=(150, 150),
input_resolutions=[{"resolution": 0.25, "units": "mpp"}]
input_resolutions=[{"resolution": 0.5, "units": "mpp"}]
)


Expand All @@ -353,7 +353,7 @@ input output configuration:
ioconfig = IOPatchPredictorConfig(
patch_input_shape=(31, 31),
stride_shape=(8, 8),
input_resolutions=[{"resolution": 0.25, "units": "mpp"}]
input_resolutions=[{"resolution": 0.5, "units": "mpp"}]
)


Expand All @@ -369,7 +369,7 @@ input output configuration:
ioconfig = IOPatchPredictorConfig(
patch_input_shape=(252, 252),
stride_shape=(150, 150),
input_resolutions=[{"resolution": 0.25, "units": "mpp"}]
input_resolutions=[{"resolution": 0.5, "units": "mpp"}]
)


Expand Down
67 changes: 67 additions & 0 deletions tests/models/test_nucleus_detection_engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Tests for NucleusDetector."""

import pathlib
import shutil

import pandas as pd
import pytest

from tiatoolbox.models.engine.nucleus_detector import (
IONucleusDetectorConfig,
NucleusDetector,
)
from tiatoolbox.utils import env_detection as toolbox_env

ON_GPU = not toolbox_env.running_on_ci() and toolbox_env.has_gpu()


def _rm_dir(path):
"""Helper func to remove directory."""
if pathlib.Path(path).exists():
shutil.rmtree(path, ignore_errors=True)


def check_output(path):
"""Check NucleusDetector output."""
coordinates = pd.read_csv(path)
assert coordinates.x[0] == pytest.approx(53, abs=2)
assert coordinates.x[1] == pytest.approx(55, abs=2)
assert coordinates.y[0] == pytest.approx(107, abs=2)
assert coordinates.y[1] == pytest.approx(127, abs=2)


def test_nucleus_detector_engine(remote_sample, tmp_path):
"""Test for nucleus detection engine."""
mini_wsi_svs = pathlib.Path(remote_sample("wsi4_512_512_svs"))

nucleus_detector = NucleusDetector(pretrained_model="mapde-conic")
_ = nucleus_detector.predict(
[mini_wsi_svs],
mode="wsi",
save_dir=tmp_path / "output",
on_gpu=ON_GPU,
)

check_output(tmp_path / "output" / "0.locations.0.csv")

_rm_dir(tmp_path / "output")

ioconfig = IONucleusDetectorConfig(
input_resolutions=[{"units": "mpp", "resolution": 0.5}],
output_resolutions=[{"units": "mpp", "resolution": 0.5}],
save_resolution=None,
patch_input_shape=[252, 252],
patch_output_shape=[252, 252],
stride_shape=[150, 150],
)

nucleus_detector = NucleusDetector(pretrained_model="mapde-conic")
_ = nucleus_detector.predict(
[mini_wsi_svs],
mode="wsi",
save_dir=tmp_path / "output",
on_gpu=ON_GPU,
ioconfig=ioconfig,
)

check_output(tmp_path / "output" / "0.locations.0.csv")
8 changes: 4 additions & 4 deletions tests/models/test_patch_predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,22 +546,22 @@ def test_io_config_delegation(remote_sample, tmp_path):
predictor = PatchPredictor(pretrained_model="resnet18-kather100k", batch_size=1)
predictor.predict(
[mini_wsi_svs],
patch_input_shape=[300, 300],
patch_input_shape=(300, 300),
mode="wsi",
on_gpu=ON_GPU,
save_dir=f"{tmp_path}/dump",
)
assert predictor._ioconfig.patch_input_shape == [300, 300]
assert predictor._ioconfig.patch_input_shape == (300, 300)
_rm_dir(f"{tmp_path}/dump")

predictor.predict(
[mini_wsi_svs],
stride_shape=[300, 300],
stride_shape=(300, 300),
mode="wsi",
on_gpu=ON_GPU,
save_dir=f"{tmp_path}/dump",
)
assert predictor._ioconfig.stride_shape == [300, 300]
assert predictor._ioconfig.stride_shape == (300, 300)
_rm_dir(f"{tmp_path}/dump")

predictor.predict(
Expand Down
49 changes: 36 additions & 13 deletions tiatoolbox/data/pretrained_model.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,6 @@ micronet-consep:
- {"units": "mpp", "resolution": 0.25}
output_resolutions:
- {"units": "mpp", "resolution": 0.25}
margin: 128
tile_shape: [2048, 2048]
patch_input_shape: [252, 252]
patch_output_shape: [252, 252]
Expand All @@ -777,66 +776,90 @@ mapde-crchisto:
architecture:
class: mapde.MapDe
kwargs:
input_resolutions:
- { "units": "mpp", "resolution": 0.25 }
num_input_channels: 3
min_distance: 4
threshold_abs: 250
num_classes: 1
ioconfig:
class: semantic_segmentor.IOSegmentorConfig
kwargs:
input_resolutions:
- { "units": "mpp", "resolution": 0.5 }
output_resolutions:
- { "units": "mpp", "resolution": 0.5 }
tile_shape: [ 2048, 2048 ]
patch_input_shape: [ 252, 252 ]
patch_output_shape: [ 252, 252 ]
stride_shape: [ 150, 150 ]
save_resolution: { 'units': 'mpp', 'resolution': 0.5 }

mapde-conic:
url: https://tiatoolbox.dcs.warwick.ac.uk/models/detection/mapde-conic.pth
architecture:
class: mapde.MapDe
kwargs:
input_resolutions:
- { "units": "mpp", "resolution": 0.25 }
num_input_channels: 3
min_distance: 3
threshold_abs: 205
num_classes: 1
ioconfig:
class: semantic_segmentor.IOSegmentorConfig
kwargs:
input_resolutions:
- { "units": "mpp", "resolution": 0.5 }
output_resolutions:
- { "units": "mpp", "resolution": 0.5 }
tile_shape: [ 2048, 2048 ]
patch_input_shape: [ 252, 252 ]
patch_output_shape: [ 252, 252 ]
stride_shape: [ 150, 150 ]
save_resolution: { 'units': 'mpp', 'resolution': 0.5 }

sccnn-crchisto:
url: https://tiatoolbox.dcs.warwick.ac.uk/models/detection/sccnn-crchisto.pth
architecture:
class: sccnn.SCCNN
kwargs:
input_resolutions:
- { "units": "mpp", "resolution": 0.25 }
num_input_channels: 3
out_height: 13
out_width: 13
radius: 12
min_distance: 6
threshold_abs: 0.20
patch_output_shape: [ 13, 13 ]
ioconfig:
class: semantic_segmentor.IOSegmentorConfig
kwargs:
input_resolutions:
- { "units": "mpp", "resolution": 0.5 }
output_resolutions:
- { "units": "mpp", "resolution": 0.5 }
tile_shape: [ 2048, 2048 ]
patch_input_shape: [ 31, 31 ]
patch_output_shape: [ 13, 13 ]
stride_shape: [ 8, 8 ]
save_resolution: { 'units': 'mpp', 'resolution': 0.5 }

sccnn-conic:
url: https://tiatoolbox.dcs.warwick.ac.uk/models/detection/sccnn-conic.pth
architecture:
class: sccnn.SCCNN
kwargs:
input_resolutions:
- { "units": "mpp", "resolution": 0.25 }
num_input_channels: 3
out_height: 13
out_width: 13
radius: 12
min_distance: 5
threshold_abs: 0.05
patch_output_shape: [ 13, 13 ]
ioconfig:
class: semantic_segmentor.IOSegmentorConfig
kwargs:
input_resolutions:
- { "units": "mpp", "resolution": 0.5 }
output_resolutions:
- { "units": "mpp", "resolution": 0.5 }
tile_shape: [ 2048, 2048 ]
patch_input_shape: [ 31, 31 ]
patch_output_shape: [ 13, 13 ]
stride_shape: [ 8, 8 ]
save_resolution: { 'units': 'mpp', 'resolution': 0.5 }

nuclick_original-pannuke:
url: https://tiatoolbox.dcs.warwick.ac.uk/models/seg/nuclick_original-pannuke.pth
Expand Down
1 change: 1 addition & 0 deletions tiatoolbox/models/engine/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Engines to run models implemented in tiatoolbox."""
from tiatoolbox.models.engine import (
nucleus_detector,
nucleus_instance_segmentor,
patch_predictor,
semantic_segmentor,
Expand Down
Loading