napari-tmidas 0.2.0__py3-none-any.whl → 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- napari_tmidas/_crop_anything.py +1895 -608
- napari_tmidas/_file_selector.py +87 -6
- napari_tmidas/_version.py +2 -2
- napari_tmidas/processing_functions/basic.py +494 -23
- napari_tmidas/processing_functions/careamics_denoising.py +324 -0
- napari_tmidas/processing_functions/careamics_env_manager.py +339 -0
- napari_tmidas/processing_functions/cellpose_env_manager.py +55 -20
- napari_tmidas/processing_functions/cellpose_segmentation.py +105 -218
- napari_tmidas/processing_functions/sam2_mp4.py +283 -0
- napari_tmidas/processing_functions/skimage_filters.py +31 -1
- napari_tmidas/processing_functions/timepoint_merger.py +490 -0
- napari_tmidas/processing_functions/trackastra_tracking.py +303 -0
- {napari_tmidas-0.2.0.dist-info → napari_tmidas-0.2.1.dist-info}/METADATA +15 -8
- {napari_tmidas-0.2.0.dist-info → napari_tmidas-0.2.1.dist-info}/RECORD +18 -13
- {napari_tmidas-0.2.0.dist-info → napari_tmidas-0.2.1.dist-info}/WHEEL +1 -1
- {napari_tmidas-0.2.0.dist-info → napari_tmidas-0.2.1.dist-info}/entry_points.txt +0 -0
- {napari_tmidas-0.2.0.dist-info → napari_tmidas-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {napari_tmidas-0.2.0.dist-info → napari_tmidas-0.2.1.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# processing_functions/cellpose_env_manager.py
|
|
2
2
|
"""
|
|
3
3
|
This module manages a dedicated virtual environment for Cellpose.
|
|
4
|
+
Updated to support Cellpose 4 (Cellpose-SAM) installation.
|
|
4
5
|
"""
|
|
5
6
|
|
|
6
7
|
import os
|
|
@@ -59,18 +60,47 @@ def create_cellpose_env():
|
|
|
59
60
|
# Path to the Python executable in the new environment
|
|
60
61
|
env_python = get_env_python_path()
|
|
61
62
|
|
|
62
|
-
# Install numpy first to ensure correct version
|
|
63
|
-
print("Installing NumPy...")
|
|
64
|
-
subprocess.check_call(
|
|
65
|
-
|
|
63
|
+
# # Install numpy first to ensure correct version
|
|
64
|
+
# print("Installing NumPy...")
|
|
65
|
+
# subprocess.check_call(
|
|
66
|
+
# [env_python, "-m", "pip", "install", "--upgrade", "pip"]
|
|
67
|
+
# )
|
|
68
|
+
# subprocess.check_call(
|
|
69
|
+
# [env_python, "-m", "pip", "install", "numpy>=1.24,<1.25"]
|
|
70
|
+
# )
|
|
71
|
+
|
|
72
|
+
# Install cellpose 4 and other dependencies
|
|
73
|
+
print(
|
|
74
|
+
"Installing Cellpose 4 (Cellpose-SAM) in the dedicated environment..."
|
|
66
75
|
)
|
|
67
|
-
|
|
68
|
-
# Install cellpose and other dependencies
|
|
69
|
-
print("Installing Cellpose in the dedicated environment...")
|
|
70
76
|
subprocess.check_call([env_python, "-m", "pip", "install", "cellpose"])
|
|
71
77
|
|
|
72
|
-
# Install
|
|
73
|
-
|
|
78
|
+
# # Install PyTorch - needed for GPU acceleration
|
|
79
|
+
# print("Installing PyTorch for GPU acceleration...")
|
|
80
|
+
# subprocess.check_call([
|
|
81
|
+
# env_python, "-m", "pip", "install",
|
|
82
|
+
# "torch", "torchvision"
|
|
83
|
+
# ])
|
|
84
|
+
|
|
85
|
+
# # Install tifffile for image handling
|
|
86
|
+
# subprocess.check_call([env_python, "-m", "pip", "install", "tifffile"])
|
|
87
|
+
|
|
88
|
+
# Check if installation was successful
|
|
89
|
+
try:
|
|
90
|
+
# Run a command to check if cellpose can be imported and GPU is available
|
|
91
|
+
result = subprocess.run(
|
|
92
|
+
[
|
|
93
|
+
env_python,
|
|
94
|
+
"-c",
|
|
95
|
+
"from cellpose import core; print(f'GPU available: {core.use_gpu()}')",
|
|
96
|
+
],
|
|
97
|
+
capture_output=True,
|
|
98
|
+
text=True,
|
|
99
|
+
check=True,
|
|
100
|
+
)
|
|
101
|
+
print(f"Cellpose environment check: {result.stdout.strip()}")
|
|
102
|
+
except subprocess.CalledProcessError as e:
|
|
103
|
+
print(f"Warning: Cellpose installation check failed: {e.stderr}")
|
|
74
104
|
|
|
75
105
|
print("Cellpose environment created successfully.")
|
|
76
106
|
return env_python
|
|
@@ -109,26 +139,32 @@ def run_cellpose_in_env(func_name, args_dict):
|
|
|
109
139
|
tifffile.imwrite(input_file.name, args_dict["image"])
|
|
110
140
|
|
|
111
141
|
# Prepare a temporary script to run Cellpose
|
|
142
|
+
# Updated to use Cellpose 4 parameters
|
|
112
143
|
script = f"""
|
|
113
144
|
import numpy as np
|
|
114
|
-
from cellpose import models
|
|
145
|
+
from cellpose import models, core
|
|
115
146
|
import tifffile
|
|
116
147
|
|
|
148
|
+
|
|
149
|
+
|
|
117
150
|
# Load image
|
|
118
151
|
image = tifffile.imread('{input_file.name}')
|
|
119
152
|
|
|
120
153
|
# Create and run model
|
|
121
|
-
model = models.
|
|
122
|
-
gpu={args_dict.get('use_gpu', True)}
|
|
123
|
-
|
|
124
|
-
)
|
|
154
|
+
model = models.CellposeModel(
|
|
155
|
+
gpu={args_dict.get('use_gpu', True)})
|
|
156
|
+
|
|
157
|
+
# Prepare normalization parameters (Cellpose 4)
|
|
158
|
+
normalize = {args_dict.get('normalize', {'tile_norm_blocksize': 128})}
|
|
125
159
|
|
|
126
|
-
# Perform segmentation
|
|
127
|
-
masks,
|
|
160
|
+
# Perform segmentation with Cellpose 4 parameters
|
|
161
|
+
masks, flows, styles = model.eval(
|
|
128
162
|
image,
|
|
129
|
-
diameter={args_dict.get('diameter', 30.0)},
|
|
130
|
-
flow_threshold={args_dict.get('flow_threshold', 0.4)},
|
|
131
163
|
channels={args_dict.get('channels', [0, 0])},
|
|
164
|
+
flow_threshold={args_dict.get('flow_threshold', 0.4)},
|
|
165
|
+
cellprob_threshold={args_dict.get('cellprob_threshold', 0.0)},
|
|
166
|
+
batch_size={args_dict.get('batch_size', 32)},
|
|
167
|
+
normalize=normalize,
|
|
132
168
|
do_3D={args_dict.get('do_3D', False)},
|
|
133
169
|
z_axis={args_dict.get('z_axis', 0)} if {args_dict.get('do_3D', False)} else None
|
|
134
170
|
)
|
|
@@ -147,10 +183,9 @@ tifffile.imwrite('{output_file.name}', masks)
|
|
|
147
183
|
result = subprocess.run(
|
|
148
184
|
[env_python, script_file.name], capture_output=True, text=True
|
|
149
185
|
)
|
|
150
|
-
|
|
186
|
+
print("Stdout:", result.stdout)
|
|
151
187
|
# Check for errors
|
|
152
188
|
if result.returncode != 0:
|
|
153
|
-
print("Stdout:", result.stdout)
|
|
154
189
|
print("Stderr:", result.stderr)
|
|
155
190
|
raise RuntimeError(
|
|
156
191
|
f"Cellpose segmentation failed: {result.stderr}"
|
|
@@ -6,10 +6,11 @@ This module provides functionality to automatically segment cells or nuclei in i
|
|
|
6
6
|
using the Cellpose deep learning-based segmentation toolkit. It supports both 2D and 3D images,
|
|
7
7
|
various dimension orders, and handles time series data.
|
|
8
8
|
|
|
9
|
+
Updated to support Cellpose 4 (Cellpose-SAM) which offers improved generalization
|
|
10
|
+
for cellular segmentation without requiring diameter parameter.
|
|
11
|
+
|
|
9
12
|
Note: This requires the cellpose library to be installed.
|
|
10
13
|
"""
|
|
11
|
-
import os
|
|
12
|
-
import sys
|
|
13
14
|
|
|
14
15
|
import numpy as np
|
|
15
16
|
|
|
@@ -91,13 +92,15 @@ def run_cellpose(
|
|
|
91
92
|
img,
|
|
92
93
|
model,
|
|
93
94
|
channels,
|
|
94
|
-
diameter,
|
|
95
95
|
flow_threshold=0.4,
|
|
96
|
+
cellprob_threshold=0.0,
|
|
96
97
|
dim_order="ZYX",
|
|
97
98
|
max_pixels=4000000,
|
|
99
|
+
tile_norm_blocksize=128,
|
|
100
|
+
batch_size=32,
|
|
98
101
|
):
|
|
99
102
|
"""
|
|
100
|
-
Run Cellpose segmentation on an image.
|
|
103
|
+
Run Cellpose segmentation on an image using Cellpose 4 (Cellpose-SAM).
|
|
101
104
|
|
|
102
105
|
Parameters:
|
|
103
106
|
-----------
|
|
@@ -107,14 +110,18 @@ def run_cellpose(
|
|
|
107
110
|
Cellpose model to use
|
|
108
111
|
channels : list
|
|
109
112
|
Channels to use for segmentation [0,0] = grayscale, [1,0] = green channel, [2,0] = red channel
|
|
110
|
-
diameter : float
|
|
111
|
-
Diameter of objects to segment
|
|
112
113
|
flow_threshold : float
|
|
113
114
|
Flow threshold for Cellpose
|
|
115
|
+
cellprob_threshold : float
|
|
116
|
+
Cell probability threshold
|
|
114
117
|
dim_order : str
|
|
115
118
|
Dimension order of the input image
|
|
116
119
|
max_pixels : int
|
|
117
120
|
Maximum number of pixels to process (for 2D images)
|
|
121
|
+
tile_norm_blocksize : int
|
|
122
|
+
Block size for tile normalization (new parameter in Cellpose 4)
|
|
123
|
+
batch_size : int
|
|
124
|
+
Batch size for processing multiple images or 3D slices at once
|
|
118
125
|
|
|
119
126
|
Returns:
|
|
120
127
|
--------
|
|
@@ -138,6 +145,9 @@ def run_cellpose(
|
|
|
138
145
|
# Check if we have a time series
|
|
139
146
|
has_time = "T" in new_dim_order
|
|
140
147
|
|
|
148
|
+
# Set up normalization with tile_norm_blocksize (Cellpose 4 parameter)
|
|
149
|
+
normalize = {"tile_norm_blocksize": tile_norm_blocksize}
|
|
150
|
+
|
|
141
151
|
if has_time:
|
|
142
152
|
# Handle time series - process each time point
|
|
143
153
|
n_timepoints = img_transposed.shape[0]
|
|
@@ -146,67 +156,58 @@ def run_cellpose(
|
|
|
146
156
|
# Process each time point
|
|
147
157
|
for t in range(n_timepoints):
|
|
148
158
|
img_t = img_transposed[t]
|
|
149
|
-
|
|
159
|
+
masks, _, _ = model.eval(
|
|
150
160
|
img_t,
|
|
151
|
-
diameter=diameter,
|
|
152
|
-
flow_threshold=flow_threshold,
|
|
153
161
|
channels=channels,
|
|
162
|
+
flow_threshold=flow_threshold,
|
|
163
|
+
cellprob_threshold=cellprob_threshold,
|
|
164
|
+
normalize=normalize,
|
|
154
165
|
z_axis=0 if is_3d else None,
|
|
155
166
|
do_3D=is_3d,
|
|
156
|
-
|
|
167
|
+
batch_size=batch_size,
|
|
157
168
|
)
|
|
158
|
-
result[t] =
|
|
169
|
+
result[t] = masks
|
|
159
170
|
else:
|
|
160
171
|
# Process single time point
|
|
161
|
-
|
|
172
|
+
masks, _, _ = model.eval(
|
|
162
173
|
img_transposed,
|
|
163
|
-
diameter=diameter,
|
|
164
|
-
flow_threshold=flow_threshold,
|
|
165
174
|
channels=channels,
|
|
175
|
+
flow_threshold=flow_threshold,
|
|
176
|
+
cellprob_threshold=cellprob_threshold,
|
|
177
|
+
normalize=normalize,
|
|
166
178
|
z_axis=0 if is_3d else None,
|
|
167
179
|
do_3D=is_3d,
|
|
168
|
-
|
|
180
|
+
batch_size=batch_size,
|
|
169
181
|
)
|
|
182
|
+
result = masks
|
|
170
183
|
|
|
171
184
|
return result.astype(np.uint32)
|
|
172
185
|
|
|
173
186
|
|
|
174
187
|
@BatchProcessingRegistry.register(
|
|
175
|
-
name="
|
|
188
|
+
name="Cellpose-SAM Segmentation",
|
|
176
189
|
suffix="_labels",
|
|
177
|
-
description="Automatic instance segmentation using Cellpose
|
|
190
|
+
description="Automatic instance segmentation using Cellpose 4 (Cellpose-SAM) with improved generalization.",
|
|
178
191
|
parameters={
|
|
179
|
-
"model_type": {
|
|
180
|
-
"type": str,
|
|
181
|
-
"default": "cyto3",
|
|
182
|
-
"description": "Cellpose model type: 'cyto'/'cyto2'/'cyto3' for cells, 'nuclei' for nuclei",
|
|
183
|
-
},
|
|
184
|
-
"diameter": {
|
|
185
|
-
"type": float,
|
|
186
|
-
"default": 40.0,
|
|
187
|
-
"min": 5.0,
|
|
188
|
-
"max": 1000.0,
|
|
189
|
-
"description": "Approximate diameter of objects to segment (pixels)",
|
|
190
|
-
},
|
|
191
192
|
"dim_order": {
|
|
192
193
|
"type": str,
|
|
193
194
|
"default": "YX",
|
|
194
195
|
"description": "Dimension order of the input (e.g., 'YX', 'ZYX', 'TZYX')",
|
|
195
196
|
},
|
|
196
|
-
"channel_1": {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
},
|
|
203
|
-
"channel_2": {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
},
|
|
197
|
+
# "channel_1": {
|
|
198
|
+
# "type": int,
|
|
199
|
+
# "default": 0,
|
|
200
|
+
# "min": 0,
|
|
201
|
+
# "max": 3,
|
|
202
|
+
# "description": "First channel: 0=grayscale, 1=green, 2=red, 3=blue",
|
|
203
|
+
# },
|
|
204
|
+
# "channel_2": {
|
|
205
|
+
# "type": int,
|
|
206
|
+
# "default": 0,
|
|
207
|
+
# "min": 0,
|
|
208
|
+
# "max": 3,
|
|
209
|
+
# "description": "Second channel: 0=none, 1=green, 2=red, 3=blue",
|
|
210
|
+
# },
|
|
210
211
|
"flow_threshold": {
|
|
211
212
|
"type": float,
|
|
212
213
|
"default": 0.4,
|
|
@@ -214,6 +215,27 @@ def run_cellpose(
|
|
|
214
215
|
"max": 0.9,
|
|
215
216
|
"description": "Flow threshold for Cellpose segmentation",
|
|
216
217
|
},
|
|
218
|
+
"cellprob_threshold": {
|
|
219
|
+
"type": float,
|
|
220
|
+
"default": 0.0,
|
|
221
|
+
"min": -6.0,
|
|
222
|
+
"max": 6.0,
|
|
223
|
+
"description": "Cell probability threshold (Cellpose 4 parameter)",
|
|
224
|
+
},
|
|
225
|
+
"tile_norm_blocksize": {
|
|
226
|
+
"type": int,
|
|
227
|
+
"default": 128,
|
|
228
|
+
"min": 32,
|
|
229
|
+
"max": 512,
|
|
230
|
+
"description": "Block size for tile normalization (Cellpose 4 parameter)",
|
|
231
|
+
},
|
|
232
|
+
"batch_size": {
|
|
233
|
+
"type": int,
|
|
234
|
+
"default": 32,
|
|
235
|
+
"min": 1,
|
|
236
|
+
"max": 128,
|
|
237
|
+
"description": "Batch size for processing multiple images/slices at once",
|
|
238
|
+
},
|
|
217
239
|
"force_dedicated_env": {
|
|
218
240
|
"type": bool,
|
|
219
241
|
"default": False,
|
|
@@ -223,20 +245,21 @@ def run_cellpose(
|
|
|
223
245
|
)
|
|
224
246
|
def cellpose_segmentation(
|
|
225
247
|
image: np.ndarray,
|
|
226
|
-
model_type: str = "cyto3",
|
|
227
|
-
diameter: float = 40.0,
|
|
228
248
|
dim_order: str = "YX",
|
|
229
249
|
channel_1: int = 0,
|
|
230
250
|
channel_2: int = 0,
|
|
231
251
|
flow_threshold: float = 0.4,
|
|
252
|
+
cellprob_threshold: float = 0.0,
|
|
253
|
+
tile_norm_blocksize: int = 128,
|
|
254
|
+
batch_size: int = 32,
|
|
232
255
|
force_dedicated_env: bool = False,
|
|
233
256
|
) -> np.ndarray:
|
|
234
257
|
"""
|
|
235
|
-
Run Cellpose segmentation on an image.
|
|
258
|
+
Run Cellpose 4 (Cellpose-SAM) segmentation on an image.
|
|
236
259
|
|
|
237
260
|
This function takes an image and performs automatic instance segmentation using
|
|
238
|
-
Cellpose
|
|
239
|
-
time series data.
|
|
261
|
+
Cellpose 4 with improved generalization for cellular segmentation. It supports
|
|
262
|
+
both 2D and 3D images, various dimension orders, and handles time series data.
|
|
240
263
|
|
|
241
264
|
If Cellpose is not available in the current environment, a dedicated virtual
|
|
242
265
|
environment will be created to run Cellpose.
|
|
@@ -245,10 +268,6 @@ def cellpose_segmentation(
|
|
|
245
268
|
-----------
|
|
246
269
|
image : numpy.ndarray
|
|
247
270
|
Input image
|
|
248
|
-
model_type : str
|
|
249
|
-
Cellpose model type: 'cyto'/'cyto2'/'cyto3' for cells, 'nuclei' for nuclei (default: "cyto3")
|
|
250
|
-
diameter : float
|
|
251
|
-
Approximate diameter of objects to segment in pixels (default: 40.0)
|
|
252
271
|
dim_order : str
|
|
253
272
|
Dimension order of the input (e.g., 'YX', 'ZYX', 'TZYX') (default: "YX")
|
|
254
273
|
channel_1 : int
|
|
@@ -257,6 +276,12 @@ def cellpose_segmentation(
|
|
|
257
276
|
Second channel: 0=none, 1=green, 2=red, 3=blue (default: 0)
|
|
258
277
|
flow_threshold : float
|
|
259
278
|
Flow threshold for Cellpose segmentation (default: 0.4)
|
|
279
|
+
cellprob_threshold : float
|
|
280
|
+
Cell probability threshold (Cellpose 4 parameter) (default: 0.0)
|
|
281
|
+
tile_norm_blocksize : int
|
|
282
|
+
Block size for tile normalization (Cellpose 4 parameter) (default: 128)
|
|
283
|
+
batch_size : int
|
|
284
|
+
Batch size for processing multiple images/slices at once (default: 32)
|
|
260
285
|
force_dedicated_env : bool
|
|
261
286
|
Force using dedicated environment even if Cellpose is available (default: False)
|
|
262
287
|
|
|
@@ -266,16 +291,8 @@ def cellpose_segmentation(
|
|
|
266
291
|
Segmented image with instance labels
|
|
267
292
|
"""
|
|
268
293
|
# Convert channel parameters to Cellpose channels list
|
|
269
|
-
channels = [channel_1, channel_2]
|
|
270
|
-
|
|
271
|
-
# Validate parameters
|
|
272
|
-
valid_models = ["cyto", "cyto2", "cyto3", "nuclei"]
|
|
273
|
-
if model_type not in valid_models:
|
|
274
|
-
raise ValueError(
|
|
275
|
-
f"Invalid model_type: {model_type}. "
|
|
276
|
-
f"Must be one of: {', '.join(valid_models)}"
|
|
277
|
-
)
|
|
278
|
-
|
|
294
|
+
# channels = [channel_1, channel_2]
|
|
295
|
+
channels = [0, 0] # limit script to single channel
|
|
279
296
|
# Determine whether to use dedicated environment
|
|
280
297
|
use_env = force_dedicated_env or USE_DEDICATED_ENV
|
|
281
298
|
|
|
@@ -293,29 +310,30 @@ def cellpose_segmentation(
|
|
|
293
310
|
# Prepare arguments for the Cellpose function
|
|
294
311
|
args = {
|
|
295
312
|
"image": image,
|
|
296
|
-
"model_type": model_type,
|
|
297
|
-
"diameter": diameter,
|
|
298
313
|
"channels": channels,
|
|
299
314
|
"flow_threshold": flow_threshold,
|
|
315
|
+
"cellprob_threshold": cellprob_threshold,
|
|
316
|
+
"normalize": {"tile_norm_blocksize": tile_norm_blocksize},
|
|
317
|
+
"batch_size": batch_size,
|
|
300
318
|
"use_gpu": USE_GPU,
|
|
301
319
|
"do_3D": "Z" in dim_order,
|
|
302
320
|
"z_axis": 0 if "Z" in dim_order else None,
|
|
303
321
|
}
|
|
304
322
|
|
|
305
323
|
# Run Cellpose in the dedicated environment
|
|
306
|
-
print(
|
|
324
|
+
print("Running Cellpose model in dedicated environment...")
|
|
307
325
|
result = run_cellpose_in_env("eval", args)
|
|
308
326
|
print(f"Segmentation complete. Found {np.max(result)} objects.")
|
|
309
327
|
return result
|
|
310
328
|
|
|
311
329
|
else:
|
|
312
|
-
print(
|
|
330
|
+
print("Running Cellpose model in current environment...")
|
|
313
331
|
# Initialize Cellpose model in current environment
|
|
314
|
-
model = models.
|
|
332
|
+
model = models.CellposeModel(gpu=USE_GPU)
|
|
315
333
|
|
|
316
334
|
# Print status information
|
|
317
335
|
gpu_status = "GPU" if USE_GPU else "CPU"
|
|
318
|
-
print(f"Using Cellpose
|
|
336
|
+
print(f"Using Cellpose on {gpu_status}")
|
|
319
337
|
print(
|
|
320
338
|
f"Processing image with shape {image.shape}, dimension order: {dim_order}"
|
|
321
339
|
)
|
|
@@ -323,7 +341,14 @@ def cellpose_segmentation(
|
|
|
323
341
|
# Run segmentation
|
|
324
342
|
try:
|
|
325
343
|
result = run_cellpose(
|
|
326
|
-
image,
|
|
344
|
+
image,
|
|
345
|
+
model,
|
|
346
|
+
channels,
|
|
347
|
+
flow_threshold,
|
|
348
|
+
cellprob_threshold,
|
|
349
|
+
dim_order,
|
|
350
|
+
tile_norm_blocksize=tile_norm_blocksize,
|
|
351
|
+
batch_size=batch_size,
|
|
327
352
|
)
|
|
328
353
|
|
|
329
354
|
print(f"Segmentation complete. Found {np.max(result)} objects.")
|
|
@@ -338,10 +363,11 @@ def cellpose_segmentation(
|
|
|
338
363
|
try:
|
|
339
364
|
args = {
|
|
340
365
|
"image": image,
|
|
341
|
-
"model_type": model_type,
|
|
342
|
-
"diameter": diameter,
|
|
343
366
|
"channels": channels,
|
|
344
367
|
"flow_threshold": flow_threshold,
|
|
368
|
+
"cellprob_threshold": cellprob_threshold,
|
|
369
|
+
"normalize": {"tile_norm_blocksize": tile_norm_blocksize},
|
|
370
|
+
"batch_size": batch_size,
|
|
345
371
|
"use_gpu": USE_GPU,
|
|
346
372
|
"do_3D": "Z" in dim_order,
|
|
347
373
|
"z_axis": 0 if "Z" in dim_order else None,
|
|
@@ -362,150 +388,11 @@ def cellpose_segmentation(
|
|
|
362
388
|
raise
|
|
363
389
|
|
|
364
390
|
|
|
365
|
-
#
|
|
366
|
-
def
|
|
367
|
-
"""
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
# Parse arguments
|
|
375
|
-
parser = argparse.ArgumentParser(
|
|
376
|
-
description="Runs automatic mask generation on images using Cellpose."
|
|
377
|
-
)
|
|
378
|
-
parser.add_argument(
|
|
379
|
-
"--input", type=str, required=True, help="Path to input images."
|
|
380
|
-
)
|
|
381
|
-
parser.add_argument(
|
|
382
|
-
"--diameter", type=float, default=40.0, help="Diameter of objects."
|
|
383
|
-
)
|
|
384
|
-
parser.add_argument(
|
|
385
|
-
"--channels",
|
|
386
|
-
type=int,
|
|
387
|
-
nargs="+",
|
|
388
|
-
default=[0, 0],
|
|
389
|
-
help="Channels to use.",
|
|
390
|
-
)
|
|
391
|
-
parser.add_argument(
|
|
392
|
-
"--dim_order",
|
|
393
|
-
type=str,
|
|
394
|
-
default="ZYX",
|
|
395
|
-
help="Dimension order of the input images.",
|
|
396
|
-
)
|
|
397
|
-
parser.add_argument(
|
|
398
|
-
"--model_type",
|
|
399
|
-
type=str,
|
|
400
|
-
default="cyto3",
|
|
401
|
-
choices=["cyto", "cyto2", "cyto3", "nuclei"],
|
|
402
|
-
help="Model type: 'cyto'/'cyto2'/'cyto3' for cells, 'nuclei' for nuclei",
|
|
403
|
-
)
|
|
404
|
-
parser.add_argument(
|
|
405
|
-
"--flow_threshold",
|
|
406
|
-
type=float,
|
|
407
|
-
default=0.4,
|
|
408
|
-
help="Flow threshold for Cellpose (default: 0.4)",
|
|
409
|
-
)
|
|
410
|
-
parser.add_argument(
|
|
411
|
-
"--max_pixels",
|
|
412
|
-
type=int,
|
|
413
|
-
default=4000000,
|
|
414
|
-
help="Maximum number of pixels to process for 2D images (default: 4000000)",
|
|
415
|
-
)
|
|
416
|
-
|
|
417
|
-
args = parser.parse_args()
|
|
418
|
-
|
|
419
|
-
# Validate input folder
|
|
420
|
-
input_folder = args.input
|
|
421
|
-
if not os.path.isdir(input_folder):
|
|
422
|
-
print(
|
|
423
|
-
f"Error: The input folder '{input_folder}' does not exist or is not accessible."
|
|
424
|
-
)
|
|
425
|
-
return 1
|
|
426
|
-
|
|
427
|
-
# Find input files
|
|
428
|
-
input_files = [
|
|
429
|
-
f
|
|
430
|
-
for f in os.listdir(input_folder)
|
|
431
|
-
if f.endswith(".tif") and not f.endswith("_labels.tif")
|
|
432
|
-
]
|
|
433
|
-
|
|
434
|
-
if not input_files:
|
|
435
|
-
print(f"No .tif files found in {input_folder}")
|
|
436
|
-
return 1
|
|
437
|
-
|
|
438
|
-
print(f"Found {len(input_files)} files to process")
|
|
439
|
-
|
|
440
|
-
# Check if Cellpose is available
|
|
441
|
-
if not CELLPOSE_AVAILABLE:
|
|
442
|
-
print(
|
|
443
|
-
"Error: Cellpose is not installed. Please install it with: pip install cellpose"
|
|
444
|
-
)
|
|
445
|
-
return 1
|
|
446
|
-
|
|
447
|
-
# Initialize model
|
|
448
|
-
model = models.Cellpose(gpu=USE_GPU, model_type=args.model_type)
|
|
449
|
-
|
|
450
|
-
# Print status
|
|
451
|
-
gpu_status = "GPU" if USE_GPU else "CPU"
|
|
452
|
-
print(f"Using Cellpose {args.model_type} model on {gpu_status}")
|
|
453
|
-
|
|
454
|
-
# Process each file
|
|
455
|
-
for input_file in tqdm(input_files, desc="Processing images"):
|
|
456
|
-
try:
|
|
457
|
-
# Check image size
|
|
458
|
-
img = imread(os.path.join(input_folder, input_file))
|
|
459
|
-
|
|
460
|
-
if len(img.shape) == 2 or (
|
|
461
|
-
len(img.shape) == 3 and "C" in args.dim_order
|
|
462
|
-
):
|
|
463
|
-
# For 2D images (potentially with channels)
|
|
464
|
-
height, width = img.shape[:2]
|
|
465
|
-
total_pixels = height * width
|
|
466
|
-
if total_pixels > args.max_pixels:
|
|
467
|
-
print(
|
|
468
|
-
f"Skipping {input_file} as it exceeds the maximum size of {args.max_pixels} pixels."
|
|
469
|
-
)
|
|
470
|
-
continue
|
|
471
|
-
|
|
472
|
-
print(
|
|
473
|
-
"\nCheck if image shape corresponds to the dim order that you have given:"
|
|
474
|
-
)
|
|
475
|
-
print(
|
|
476
|
-
f"Image shape: {img.shape}, dimension order: {args.dim_order}\n"
|
|
477
|
-
)
|
|
478
|
-
|
|
479
|
-
# Run segmentation
|
|
480
|
-
result = run_cellpose(
|
|
481
|
-
img,
|
|
482
|
-
model,
|
|
483
|
-
args.channels,
|
|
484
|
-
args.diameter,
|
|
485
|
-
args.flow_threshold,
|
|
486
|
-
args.dim_order,
|
|
487
|
-
args.max_pixels,
|
|
488
|
-
)
|
|
489
|
-
|
|
490
|
-
# Save result
|
|
491
|
-
output_file = os.path.join(
|
|
492
|
-
input_folder, input_file.replace(".tif", "_labels.tif")
|
|
493
|
-
)
|
|
494
|
-
imwrite(output_file, result, compression="zlib")
|
|
495
|
-
|
|
496
|
-
print(
|
|
497
|
-
f"Saved segmentation with {np.max(result)} objects to {output_file}"
|
|
498
|
-
)
|
|
499
|
-
|
|
500
|
-
except (Exception, MemoryError) as e:
|
|
501
|
-
print(f"Error processing {input_file}: {str(e)}")
|
|
502
|
-
|
|
503
|
-
print("\nProcessing complete.")
|
|
504
|
-
return 0
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
# Run the command-line function if this script is run directly
|
|
508
|
-
if __name__ == "__main__":
|
|
509
|
-
import sys
|
|
510
|
-
|
|
511
|
-
sys.exit(run_cellpose_segmentation())
|
|
391
|
+
# Update cellpose_env_manager.py to install Cellpose 4
|
|
392
|
+
def update_cellpose_env_manager():
|
|
393
|
+
"""
|
|
394
|
+
Update the cellpose_env_manager to install Cellpose 4
|
|
395
|
+
"""
|
|
396
|
+
# This function can be called to update the environment manager code
|
|
397
|
+
# For example, by modifying the pip install command to install the latest version
|
|
398
|
+
# or specify Cellpose 4 explicitly
|