Skip to content

Commit 5f5b9fe

Browse files
Merge pull request #287 from BodenmillerGroup/cellpose_sam
Cellpose sam
2 parents 0001cd6 + 3a807ff commit 5f5b9fe

File tree

7 files changed

+125
-115
lines changed

7 files changed

+125
-115
lines changed

AUTHORS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
Created and maintained by [Jonas Windhager](mailto:jonas@windhager.io) until February 2023.
44

5-
Maintained by [Milad Adibi](mailto:milad.adibi@uzh.ch) from February 2023.
5+
Maintained by [Victor Ibañez](mailto:victor.ibanez@uzh.ch) from February 2023.

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.16.4] - 2026-02-26
9+
10+
### Changed
11+
12+
- Updated readimc to 0.9.2
13+
- Changed Cellpose container and description to v4.0.8, using CellposeSAM
14+
815
## [0.16.3] - 2024-05-29
916

1017
### Changed

Dockerfile

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ARG FIXUID_VERSION="0.5.1"
1515
ARG ILASTIK_BINARY="ilastik-1.3.3post3-Linux.tar.bz2"
1616
ARG CELLPROFILER_VERSION="4.2.5"
1717
ARG CELLPROFILER_PLUGINS_VERSION="4.2.1"
18-
ARG CELLPOSE_VERSION="2.2"
18+
ARG CELLPOSE_VERSION="4.0.8"
1919

2020
########## TENSORFLOW ##########
2121

@@ -186,22 +186,8 @@ RUN python -m pip install "cellpose==${CELLPOSE_VERSION}"
186186
USER steinbock:steinbock
187187

188188
RUN mkdir -p /home/steinbock/.cellpose/models && \
189-
cd /home/steinbock/.cellpose/models && \
190-
curl -SsO https://www.cellpose.org/models/cytotorch_0 && \
191-
curl -SsO https://www.cellpose.org/models/cytotorch_1 && \
192-
curl -SsO https://www.cellpose.org/models/cytotorch_2 && \
193-
curl -SsO https://www.cellpose.org/models/cytotorch_3 && \
194-
curl -SsO https://www.cellpose.org/models/size_cytotorch_0.npy && \
195-
curl -SsO https://www.cellpose.org/models/nucleitorch_0 && \
196-
curl -SsO https://www.cellpose.org/models/nucleitorch_1 && \
197-
curl -SsO https://www.cellpose.org/models/nucleitorch_2 && \
198-
curl -SsO https://www.cellpose.org/models/nucleitorch_3 && \
199-
curl -SsO https://www.cellpose.org/models/size_nucleitorch_0.npy && \
200-
curl -SsO https://www.cellpose.org/models/cyto2torch_0 && \
201-
curl -SsO https://www.cellpose.org/models/cyto2torch_1 && \
202-
curl -SsO https://www.cellpose.org/models/cyto2torch_2 && \
203-
curl -SsO https://www.cellpose.org/models/cyto2torch_3 && \
204-
curl -SsO https://www.cellpose.org/models/size_cyto2torch_0.npy
189+
curl -L -sS -o /home/steinbock/.cellpose/models/cpsam \
190+
https://huggingface.co/mouseland/cellpose-sam/resolve/main/cpsam
205191

206192

207193

docs/cli/segmentation.md

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ This will create grayscale cell/nuclear masks of the same x and y dimensions as
9696

9797
## Cellpose
9898

99-
!!! danger "Experimental feature"
100-
This is an experimental feature and is only available in the `-cellpose` flavors of the *steinbock* Docker container.
99+
100+
!!! This feature is only available in the `-cellpose` flavors of the *steinbock* Docker container.
101101

102102
Segmentation using cellpose likely requires fine-tuning of parameters, e.g. using steinbock command-line interface options.
103103

@@ -106,22 +106,16 @@ This will create grayscale cell/nuclear masks of the same x and y dimensions as
106106
!!! note "End-to-end cell segmentation"
107107
This approach operates directly on image intensities and does not require a preceding pixel classification step.
108108

109-
To segment cells using the default `cyto2` model:
110-
111-
steinbock segment cellpose --minmax
109+
To segment nuclei or cells using the default `cpsam` model:
112110

113-
To segment nuclei using the `nuclei` model:
114-
115-
steinbock segment cellpose --minmax --model nuclei
111+
steinbock segment cellpose
116112

117113
!!! note "Cellpose image data"
118-
Cellpose expects two-channel images as input, where the first channel must be a nuclear channel (e.g. DAPI) and the second channel must be a cytoplasmic channel (e.g. E-Cadherin). The nuclear channel is optional and only the cytoplasmic channel ("channel to segment") is required. Note that - compared to the original cellpose implementation - the channel order is reversed for compatibility with DeepCell/Mesmer.
114+
For cell segmentation, Cellpose expects maximum 3-channel images as input, where one channel should be a nuclear channel (e.g. DAPI) and the second channel should be a cytoplasmic channel (e.g. E-Cadherin), the order does not matter anymore in v4+. For nuclei segmentation, only a nuclei channel should be provided and the parameter `--diameter` has to be adjusted accordingly.
119115

120-
If a `cellpose` column is present in the *steinbock* panel file, channels are sorted and grouped according to values in that column to generate the required input for DeepCell: For each image, each group of channels is aggregated by computing the mean along the channel axis (use the `--aggr` option to specify a different aggregation strategy). The resulting images consist of one channel per group; channels without a group label are ignored.
116+
If a `cellpose` column is present in the *steinbock* panel file, channels are sorted and grouped according to values in that column to generate the required input for Cellpose: For each image, each group of channels is aggregated by computing the mean along the channel axis (use the `--aggr` option to specify a different aggregation strategy). The resulting images consist of one channel per group; channels without a group label are ignored.
121117

122118
If no `cellpose` column is present, images are expected to be in the correct format already.
123119

124120
!!! note "GPU support"
125-
Currently. steinbock does not support cellpose segmentation with GPU support.
126-
127-
If GPU support is required, consider running cellpose on your host system independently.
121+
In Cellpose v4+ GPU usage is supported inherently - there is a check whether GPU devices are available, otherwise it will fall back to CPU usage.

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ name = steinbock
33
url = https://github.com/BodenmillerGroup/steinbock
44
author = Jonas Windhager
55
author_email = jonas@windhager.io
6-
maintainer = Milad Adibi
7-
maintainer_email = milad.adibi@uzh.ch
6+
maintainer = Victor Ibañez
7+
maintainer_email = victor.ibanez@uzh.ch
88
classifiers =
99
Operating System :: OS Independent
1010
Programming Language :: Python :: 3

steinbock/segmentation/_cli/cellpose.py

Lines changed: 78 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,8 @@
1313
cellpose_cli_available = cellpose.cellpose_available
1414

1515

16-
@click.command(name="cellpose", help="Run an object segmentation batch using Cellpose")
17-
@click.option(
18-
"--model",
19-
"model_name",
20-
type=click.Choice(["nuclei", "cyto", "cyto2"]),
21-
default="cyto2",
22-
show_default=True,
23-
help="Name of the Cellpose model",
16+
@click.command(
17+
name="cellpose", help="Run an object segmentation batch using CellposeSAM"
2418
)
2519
@click.option(
2620
"--img",
@@ -60,13 +54,6 @@
6054
show_default=True,
6155
help="Numpy function for aggregating channel pixels",
6256
)
63-
@click.option(
64-
"--net-avg/--no-net-avg",
65-
"net_avg",
66-
default=True,
67-
show_default=True,
68-
help="See Cellpose documentation",
69-
)
7057
@click.option(
7158
"--batch-size",
7259
"batch_size",
@@ -76,45 +63,48 @@
7663
help="See Cellpose documentation",
7764
)
7865
@click.option(
79-
"--normalize/--no-normalize",
80-
"normalize",
81-
default=True,
66+
"--resample/--no-resample",
67+
"resample",
68+
default=False,
8269
show_default=True,
8370
help="See Cellpose documentation",
8471
)
8572
@click.option(
86-
"--diameter",
87-
"diameter",
88-
type=click.FLOAT,
89-
help="See Cellpose documentation",
73+
"--channel-axis",
74+
"channel_axis",
75+
type=click.INT,
76+
default=0,
77+
show_default=True,
78+
help="See Cellpose documentation.",
9079
)
9180
@click.option(
92-
"--tile/--no-tile",
93-
"tile",
94-
default=False,
81+
"--normalize/--no-normalize",
82+
"normalize",
83+
default=True,
9584
show_default=True,
9685
help="See Cellpose documentation",
9786
)
9887
@click.option(
99-
"--tile-overlap",
100-
"tile_overlap",
101-
type=click.FLOAT,
102-
default=0.1,
88+
"--invert/--no-invert",
89+
"invert",
90+
default=False,
10391
show_default=True,
10492
help="See Cellpose documentation",
10593
)
10694
@click.option(
107-
"--resample/--no-resample",
108-
"resample",
109-
default=True,
110-
show_default=True,
95+
"--rescale",
96+
"rescale",
97+
type=click.FLOAT,
98+
default=None,
99+
show_default=False,
111100
help="See Cellpose documentation",
112101
)
113102
@click.option(
114-
"--interp/--no-interp",
115-
"interp",
116-
default=True,
117-
show_default=True,
103+
"--diameter",
104+
"diameter",
105+
type=click.FLOAT,
106+
default=None,
107+
show_default=False,
118108
help="See Cellpose documentation",
119109
)
120110
@click.option(
@@ -126,8 +116,8 @@
126116
help="See Cellpose documentation",
127117
)
128118
@click.option(
129-
"--cellprobab-threshold",
130-
"cellprobab_threshold",
119+
"--cellprob-threshold",
120+
"cellprob_threshold",
131121
type=click.FLOAT,
132122
default=0.0,
133123
show_default=True,
@@ -141,6 +131,36 @@
141131
show_default=True,
142132
help="See Cellpose documentation",
143133
)
134+
@click.option(
135+
"--max-size-fraction",
136+
"max_size_fraction",
137+
type=click.FLOAT,
138+
default=0.4,
139+
show_default=True,
140+
help="See Cellpose documentation",
141+
)
142+
@click.option(
143+
"--niter",
144+
"niter",
145+
type=click.INT,
146+
default=None,
147+
help="See Cellpose documentation",
148+
)
149+
@click.option(
150+
"--augment/--no-augment",
151+
"augment",
152+
default=False,
153+
show_default=True,
154+
help="See Cellpose documentation",
155+
)
156+
@click.option(
157+
"--tile-overlap",
158+
"tile_overlap",
159+
type=click.FLOAT,
160+
default=0.1,
161+
show_default=True,
162+
help="See Cellpose documentation",
163+
)
144164
@click.option(
145165
"-o",
146166
"mask_dir",
@@ -152,23 +172,25 @@
152172
@click_log.simple_verbosity_option(logger=steinbock_logger)
153173
@catch_exception(handle=SteinbockException)
154174
def cellpose_cmd(
155-
model_name: str,
156175
img_dir,
157176
channelwise_minmax,
158177
channelwise_zscore,
159178
panel_file,
160179
aggr_func_name,
161-
net_avg,
162180
batch_size,
181+
resample,
182+
channel_axis,
163183
normalize,
184+
invert,
185+
rescale,
164186
diameter,
165-
tile,
166-
tile_overlap,
167-
resample,
168-
interp,
169187
flow_threshold,
170-
cellprobab_threshold,
188+
cellprob_threshold,
171189
min_size,
190+
max_size_fraction,
191+
niter,
192+
augment,
193+
tile_overlap,
172194
mask_dir,
173195
):
174196
channel_groups = None
@@ -179,24 +201,26 @@ def cellpose_cmd(
179201
aggr_func = getattr(np, aggr_func_name)
180202
img_files = io.list_image_files(img_dir)
181203
Path(mask_dir).mkdir(exist_ok=True)
182-
for img_file, mask, flow, style, diam in cellpose.try_segment_objects(
183-
model_name,
204+
for img_file, mask, _, _ in cellpose.try_segment_objects(
184205
img_files,
185206
channelwise_minmax=channelwise_minmax,
186207
channelwise_zscore=channelwise_zscore,
187208
channel_groups=channel_groups,
188209
aggr_func=aggr_func,
189-
net_avg=net_avg,
190210
batch_size=batch_size,
211+
resample=resample,
212+
channel_axis=channel_axis,
191213
normalize=normalize,
214+
invert=invert,
215+
rescale=rescale,
192216
diameter=diameter,
193-
tile=tile,
194-
tile_overlap=tile_overlap,
195-
resample=resample,
196-
interp=interp,
197217
flow_threshold=flow_threshold,
198-
cellprob_threshold=cellprobab_threshold,
218+
cellprob_threshold=cellprob_threshold,
199219
min_size=min_size,
220+
max_size_fraction=max_size_fraction,
221+
niter=niter,
222+
augment=augment,
223+
tile_overlap=tile_overlap,
200224
):
201225
mask_file = io._as_path_with_suffix(Path(mask_dir) / img_file.name, ".tiff")
202226
io.write_mask(mask, mask_file)

0 commit comments

Comments
 (0)