Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
ca37400
Merge pull request #1 from TissueImageAnalytics/develop
mbasheer04 Jan 17, 2025
dab2693
Merge branch 'TissueImageAnalytics:develop' into develop
mbasheer04 Jan 24, 2025
bc6afda
Squashed commit of the following:
mbasheer04 Jan 24, 2025
5f8032d
Merge branch 'develop' of https://github.com/mbasheer04/tiatoolbox in…
mbasheer04 Jan 24, 2025
a543460
Integrating SAM into bokeh
mbasheer04 Jan 30, 2025
c620ca4
Added save file for GeneralSegmentor output
mbasheer04 Jan 30, 2025
9217b69
Added on-click prompt segementation to TIAViz
mbasheer04 Feb 19, 2025
60f4d5f
Added multi-prompt segmentation & bounding-box
mbasheer04 Feb 20, 2025
09a79fd
Added scores to masks
mbasheer04 Feb 22, 2025
1a4a76c
Attempting to add resolution/window-based segmentation
mbasheer04 Feb 26, 2025
b322539
Successfully implemented window-based segmentation
mbasheer04 Feb 27, 2025
35237c4
Fixing issues
mbasheer04 Mar 4, 2025
6ad56fe
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 20, 2025
2cb7d9c
Merge branch 'develop' into sam-viz
shaneahmed Mar 21, 2025
7b403c9
Preparing for PR
mbasheer04 Mar 20, 2025
a8f2938
Merge branch 'sam-viz' of https://github.com/mbasheer04/tiatoolbox in…
mbasheer04 Mar 27, 2025
6e8b859
Restoring notebook changes
mbasheer04 Mar 27, 2025
51ecbe9
Pre-commit fixes
mbasheer04 Mar 28, 2025
fd3a2c2
Added centroid extraction
mbasheer04 Apr 3, 2025
315d2c8
Merge branch 'develop' into sam-viz
shaneahmed Apr 4, 2025
a5d5971
Merge branch 'develop' into sam-viz
adamshephard Apr 10, 2025
ec9b76c
Improving Engine
mbasheer04 Apr 11, 2025
5db9657
Removing eval files
mbasheer04 Apr 11, 2025
e193646
Merge branch 'sam-viz' of https://github.com/mbasheer04/tiatoolbox in…
mbasheer04 Apr 11, 2025
effdadc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 11, 2025
f69dfb7
Cleaning up code
mbasheer04 Apr 11, 2025
c02f153
Merge branch 'sam-viz' of https://github.com/mbasheer04/tiatoolbox in…
mbasheer04 Apr 11, 2025
c1cb059
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 11, 2025
71eedb2
Added docstrings
mbasheer04 Apr 16, 2025
0878a66
Added SAM to requirements.txt
mbasheer04 Apr 17, 2025
65d72aa
Added pretrained model and fixed requirements
mbasheer04 Apr 24, 2025
be52c04
Adding engine unit tests
mbasheer04 Apr 25, 2025
2517844
Improving unit tests
mbasheer04 Apr 25, 2025
210ad2d
Improving unit tests
mbasheer04 Apr 29, 2025
821a848
Add store from #926
mbasheer04 Apr 29, 2025
5bf382b
Added annotation-based save for engine
mbasheer04 May 1, 2025
b5afc18
Merge branch 'develop' into sam-viz
mbasheer04 May 2, 2025
fbfa884
Fixing DeepSource issues
mbasheer04 May 2, 2025
37939c3
Merge branch 'sam-viz' of https://github.com/mbasheer04/tiatoolbox in…
mbasheer04 May 2, 2025
673c318
Debugging engine
mbasheer04 May 7, 2025
63d8012
Switched to transformers
mbasheer04 May 8, 2025
5c3656a
Finishing unit tests
mbasheer04 May 9, 2025
fd0539e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 9, 2025
01af916
Fixing deepsource
mbasheer04 May 9, 2025
311295d
Merge branch 'develop' into sam-viz
mbasheer04 May 9, 2025
c992fc8
Merge branch 'sam-viz' of https://github.com/mbasheer04/tiatoolbox in…
mbasheer04 May 9, 2025
4765906
Fixing build errors
mbasheer04 May 9, 2025
73150f2
Merge branch 'develop' into sam-viz
mbasheer04 May 9, 2025
7f122b3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 9, 2025
cc4f883
Fixing more build errors
mbasheer04 May 9, 2025
9c0e1bd
Merge branch 'sam-viz' of https://github.com/mbasheer04/tiatoolbox in…
mbasheer04 May 9, 2025
53374aa
Fixing arch test
mbasheer04 May 9, 2025
0e13290
Removed whole image mask generation
mbasheer04 May 10, 2025
6190647
Added missing exception tests
mbasheer04 May 10, 2025
94e09f1
Fixed image encoding to work with non-square images
mbasheer04 May 11, 2025
c24016c
Fixing issues with tile mode
mbasheer04 May 12, 2025
c7d3dc6
Fixed TIAViz issues
mbasheer04 May 12, 2025
85b1148
Added mask again
mbasheer04 May 12, 2025
2499251
initial fix
measty Oct 18, 2025
660a118
remove old promptsegmentor
measty Nov 7, 2025
b1d92b0
Merge branch 'develop' of https://github.com/TissueImageAnalytics/tia…
measty Nov 7, 2025
442e8a9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 7, 2025
c4869f2
Merge branch 'develop' into sam-viz-fix
shaneahmed Nov 28, 2025
3a58797
Merge branch 'develop' into sam-viz-fix
shaneahmed Dec 5, 2025
8a47302
Merge branch 'develop' into sam-viz-fix
shaneahmed Dec 19, 2025
a0781fb
Merge branch 'develop' into sam-viz-fix
shaneahmed Jan 9, 2026
6fc325e
Merge branch 'develop' of https://github.com/TissueImageAnalytics/tia…
measty Jan 15, 2026
929d405
remove outdated tests
measty Jan 15, 2026
89a69a7
precommit fixes
measty Jan 15, 2026
0df23b0
scale attribute
measty Jan 15, 2026
0a5ece9
update test
measty Jan 15, 2026
e285c53
standardize inputs
measty Jan 15, 2026
82b30b2
fix test
measty Jan 15, 2026
95851a8
revert unecessary change
measty Jan 15, 2026
a4aa37e
add test
measty Jan 16, 2026
6c72547
deepsource...
measty Jan 16, 2026
b84ef7f
coverage
measty Jan 16, 2026
8ccf953
fix offset
measty Jan 16, 2026
d44ed93
mix box and pts
measty Jan 16, 2026
4fb94a8
coverage
measty Jan 16, 2026
44e99d1
Merge branch 'develop' into sam-viz-fix
shaneahmed Jan 22, 2026
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
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ ci:
autofix_prs: true
autoupdate_commit_msg: ':technologist: pre-commit autoupdate'
autoupdate_schedule: 'monthly'
default_language_version:
python: python3.12
repos:
- repo: local
hooks:
Expand Down
1 change: 1 addition & 0 deletions requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ timm>=1.0.3
torch>=2.5.0
torchvision>=0.15.0
tqdm>=4.64.1
transformers>=4.51.1
umap-learn>=0.5.3
wsidicom>=0.18.0
zarr>=2.13.3, <3.0.0
63 changes: 63 additions & 0 deletions tests/models/test_arch_sam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""Unit test package for SAM."""

from collections.abc import Callable
from pathlib import Path

import numpy as np
import pytest
import torch

from tiatoolbox.models.architecture.sam import SAM
from tiatoolbox.utils import env_detection as toolbox_env
from tiatoolbox.utils import imread
from tiatoolbox.utils.misc import select_device

ON_GPU = toolbox_env.has_gpu()

# Test pretrained Model =============================


def test_functional_sam(remote_sample: Callable) -> None:
"""Test for SAM."""
# convert to pathlib Path to prevent wsireader complaint
tile_path = Path(remote_sample("patch-extraction-vf"))
img = imread(tile_path)

# test creation

model = SAM(device=select_device(on_gpu=ON_GPU))

# create image patch and prompts
patch = img[63:191, 750:878, :]

points = np.array([[[64, 64]]])
boxes = np.array([[[64, 64, 128, 128]]])

# test preproc
tensor = torch.from_numpy(img)
patch = np.expand_dims(model.preproc(tensor), axis=0)
patch = model.preproc(patch)

# test inference

mask_output, score_output = model.infer_batch(
model, patch, points, device=select_device(on_gpu=ON_GPU)
)

assert mask_output is not None, "Output should not be None"
assert len(mask_output) > 0, "Output should have at least one element"
assert len(score_output) > 0, "Output should have at least one element"

mask_output, score_output = model.infer_batch(
model, patch, box_coords=boxes, device=select_device(on_gpu=ON_GPU)
)

assert len(mask_output) > 0, "Output should have at least one element"
assert len(score_output) > 0, "Output should have at least one element"

# test error when no prompts provided
with pytest.raises(
ValueError,
match=r"At least one of point_coords or box_coords must be provided.",
):
_ = model.infer_batch(model, patch, device=select_device(on_gpu=ON_GPU))
53 changes: 53 additions & 0 deletions tests/models/test_prompt_segmentor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Unit test package for prompt segmentor."""

from pathlib import Path

import cv2
import numpy as np

from tiatoolbox.annotation.storage import SQLiteStore
from tiatoolbox.models.architecture.sam import SAM
from tiatoolbox.models.engine.prompt_segmentor import PromptSegmentor


def test_prompt_segmentor(track_tmp_path: Path) -> None:
"""Test for Prompt Segmentor."""
# create dummy image patch 256x256x3 with small circle in middle
img = np.zeros((256, 256, 3), dtype=np.uint8)
cv2.circle(img, (128, 128), 50, (255, 255, 255), -1)

expected_area = np.pi * (50**2)

# prompt with pt in center of circle
points = np.array([[[128, 128]]], np.uint32)
boxes = None

# instantiate prompt segmentor with SAM model
sam_model = SAM()
prompt_segmentor = PromptSegmentor(model=sam_model)

# run prediction
output_paths = prompt_segmentor.run(
images=[img],
point_coords=points,
box_coords=boxes,
save_dir=track_tmp_path / "sam_test_output",
device="cpu",
)

assert isinstance(output_paths, list), "Output should be a list of paths"
assert len(output_paths) == 1, "Output list should contain one path"

# load the saved annotation db
store = SQLiteStore(output_paths[0])
ann = next(iter(store.values()))
# area should be close to expected area
assert abs(ann.geometry.area - expected_area) < expected_area * 0.1, (
"should segment circle area correctly"
)

# check with model=None
prompt_segmentor_default = PromptSegmentor(model=None)
assert isinstance(prompt_segmentor_default.model, SAM), (
"Default model should be SAM"
)
46 changes: 46 additions & 0 deletions tests/test_app_bokeh.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,52 @@ def test_hovernet_on_box(doc: Document, data_path: pytest.TempPathFactory) -> No
assert len(main.UI["type_column"].children) == 1


def test_sam_segment(doc: Document, data_path: pytest.TempPathFactory) -> None:
"""Test running SAM on points and a box."""
slide_select = doc.get_model_by_name("slide_select0")
slide_select.value = [data_path["slide2"].name]
run_button = doc.get_model_by_name("to_model0")
assert len(main.UI["color_column"].children) == 0
slide_select.value = [data_path["slide1"].name]
# set up a box selection
main.UI["box_source"].data = {
"x": [1200],
"y": [-2000],
"width": [400],
"height": [400],
}

# select SAM model and run it on box
model_select = doc.get_model_by_name("model_drop0")
model_select.value = "SAM"

click = ButtonClick(run_button)
run_button._trigger_event(click)
assert len(main.UI["color_column"].children) > 0

# test save functionality
save_button = doc.get_model_by_name("save_button0")
click = ButtonClick(save_button)
save_button._trigger_event(click)
saved_path = (
data_path["base_path"]
/ "overlays"
/ (data_path["slide1"].stem + "_saved_anns.db")
)
assert saved_path.exists()

# load an overlay with different types
cprop_select = doc.get_model_by_name("cprop0")
cprop_select.value = ["prob"]
layer_drop = doc.get_model_by_name("layer_drop0")
click = MenuItemClick(layer_drop, str(data_path["dat_anns"]))
layer_drop._trigger_event(click)
assert main.UI["vstate"].types == ["annotation"]
# check the per-type ui controls have been updated
assert len(main.UI["color_column"].children) == 1
assert len(main.UI["type_column"].children) == 1


def test_alpha_sliders(doc: Document) -> None:
"""Test sliders for adjusting slide and overlay alpha."""
slide_alpha = doc.get_model_by_name("slide_alpha0")
Expand Down
4 changes: 4 additions & 0 deletions tiatoolbox/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .architecture.mapde import MapDe
from .architecture.micronet import MicroNet
from .architecture.nuclick import NuClick
from .architecture.sam import SAM
from .architecture.sccnn import SCCNN
from .engine.multi_task_segmentor import MultiTaskSegmentor
from .engine.nucleus_instance_segmentor import NucleusInstanceSegmentor
Expand All @@ -17,6 +18,7 @@
PatchPredictor,
WSIPatchDataset,
)
from .engine.prompt_segmentor import PromptSegmentor
from .engine.semantic_segmentor import (
DeepFeatureExtractor,
IOSegmentorConfig,
Expand All @@ -25,6 +27,7 @@
)

__all__ = [
"SAM",
"SCCNN",
"HoVerNet",
"HoVerNetPlus",
Expand All @@ -35,5 +38,6 @@
"NuClick",
"NucleusInstanceSegmentor",
"PatchPredictor",
"PromptSegmentor",
"SemanticSegmentor",
]
Loading
Loading