deepliif 1.1.9__tar.gz → 1.1.10__tar.gz
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.
- {deepliif-1.1.9/deepliif.egg-info → deepliif-1.1.10}/PKG-INFO +171 -26
- {deepliif-1.1.9 → deepliif-1.1.10}/README.md +170 -25
- {deepliif-1.1.9 → deepliif-1.1.10}/cli.py +49 -42
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/aligned_dataset.py +17 -0
- deepliif-1.1.10/deepliif/models/SDG_model.py +189 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/__init__.py +109 -44
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/__init__.py +62 -29
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/__init__.py +22 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/util.py +17 -1
- {deepliif-1.1.9 → deepliif-1.1.10/deepliif.egg-info}/PKG-INFO +171 -26
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/SOURCES.txt +1 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/setup.cfg +1 -1
- {deepliif-1.1.9 → deepliif-1.1.10}/setup.py +1 -1
- {deepliif-1.1.9 → deepliif-1.1.10}/tests/test_cli_inference.py +170 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/tests/test_cli_serialize.py +1 -1
- {deepliif-1.1.9 → deepliif-1.1.10}/LICENSE.md +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/__init__.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/__init__.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/base_dataset.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/colorization_dataset.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/image_folder.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/single_dataset.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/template_dataset.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/unaligned_dataset.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/DeepLIIFExt_model.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/DeepLIIF_model.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/base_model.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/networks.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/base_options.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/processing_options.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/test_options.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/train_options.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/postprocessing.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/train.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/get_data.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/html.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/image_pool.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/visualizer.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/dependency_links.txt +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/entry_points.txt +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/requires.txt +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/top_level.txt +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/tests/test_args.py +0 -0
- {deepliif-1.1.9 → deepliif-1.1.10}/tests/test_cli_train.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: deepliif
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.10
|
|
4
4
|
Summary: DeepLIIF: Deep-Learning Inferred Multiplex Immunofluorescence for Immunohistochemical Image Quantification
|
|
5
5
|
Home-page: https://github.com/nadeemlab/DeepLIIF
|
|
6
6
|
Author: Parmida93
|
|
@@ -51,6 +51,9 @@ segmentation.*
|
|
|
51
51
|
|
|
52
52
|
© This code is made available for non-commercial academic purposes.
|
|
53
53
|
|
|
54
|
+

|
|
55
|
+
[](https://pepy.tech/project/deepliif?&left_text=totalusers)
|
|
56
|
+
|
|
54
57
|
*Overview of DeepLIIF pipeline and sample input IHCs (different
|
|
55
58
|
brown/DAB markers -- BCL2, BCL6, CD10, CD3/CD8, Ki67) with corresponding DeepLIIF-generated hematoxylin/mpIF modalities
|
|
56
59
|
and classified (positive (red) and negative (blue) cell) segmentation masks. (a) Overview of DeepLIIF. Given an IHC
|
|
@@ -122,7 +125,7 @@ deepliif prepare-training-data --input-dir /path/to/input/images
|
|
|
122
125
|
To train a model:
|
|
123
126
|
```
|
|
124
127
|
deepliif train --dataroot /path/to/input/images
|
|
125
|
-
|
|
128
|
+
--name Model_Name
|
|
126
129
|
```
|
|
127
130
|
or
|
|
128
131
|
```
|
|
@@ -168,7 +171,7 @@ The installed `deepliif` uses Dask to perform inference on the input IHC images.
|
|
|
168
171
|
Before running the `test` command, the model files must be serialized using Torchscript.
|
|
169
172
|
To serialize the model files:
|
|
170
173
|
```
|
|
171
|
-
deepliif serialize --
|
|
174
|
+
deepliif serialize --model-dir /path/to/input/model/files
|
|
172
175
|
--output-dir /path/to/output/model/files
|
|
173
176
|
```
|
|
174
177
|
* By default, the model files are expected to be located in `DeepLIIF/model-server/DeepLIIF_Latest_Model`.
|
|
@@ -177,15 +180,17 @@ deepliif serialize --models-dir /path/to/input/model/files
|
|
|
177
180
|
## Testing
|
|
178
181
|
To test the model:
|
|
179
182
|
```
|
|
180
|
-
deepliif test --input-dir /path/to/input/images
|
|
181
|
-
--output-dir /path/to/output/images
|
|
182
|
-
--model-dir path/to/the/serialized/model
|
|
183
|
+
deepliif test --input-dir /path/to/input/images
|
|
184
|
+
--output-dir /path/to/output/images
|
|
185
|
+
--model-dir /path/to/the/serialized/model
|
|
183
186
|
--tile-size 512
|
|
184
187
|
```
|
|
185
188
|
or
|
|
186
189
|
```
|
|
187
|
-
python test.py --dataroot /path/to/input/images
|
|
188
|
-
--
|
|
190
|
+
python test.py --dataroot /path/to/input/images
|
|
191
|
+
--results_dir /path/to/output/images
|
|
192
|
+
--checkpoints_dir /path/to/model/files
|
|
193
|
+
--name Model_Name
|
|
189
194
|
```
|
|
190
195
|
* The latest version of the pretrained models can be downloaded [here](https://zenodo.org/record/4751737#.YKRTS0NKhH4).
|
|
191
196
|
* Before running test on images, the model files must be serialized as described above.
|
|
@@ -206,7 +211,7 @@ Based on the available GPU resources, the region-size can be changed.
|
|
|
206
211
|
```
|
|
207
212
|
deepliif test --input-dir /path/to/input/images
|
|
208
213
|
--output-dir /path/to/output/images
|
|
209
|
-
--model-dir path/to/the/serialized/model
|
|
214
|
+
--model-dir /path/to/the/serialized/model
|
|
210
215
|
--tile-size 512
|
|
211
216
|
--region-size 20000
|
|
212
217
|
```
|
|
@@ -247,25 +252,61 @@ If you don't have access to GPU or appropriate hardware and don't want to instal
|
|
|
247
252
|
|
|
248
253
|

|
|
249
254
|
|
|
250
|
-
|
|
251
|
-
|
|
255
|
+
## Cloud API Endpoints
|
|
256
|
+
|
|
257
|
+
DeepLIIF can also be accessed programmatically through an endpoint by posting a multipart-encoded request containing the original image file, along with optional parameters including postprocessing thresholds:
|
|
252
258
|
|
|
253
259
|
```
|
|
254
260
|
POST /api/infer
|
|
255
261
|
|
|
256
|
-
|
|
262
|
+
File Parameter:
|
|
263
|
+
|
|
264
|
+
img (required)
|
|
265
|
+
Image on which to run DeepLIIF.
|
|
266
|
+
|
|
267
|
+
Query String Parameters:
|
|
268
|
+
|
|
269
|
+
resolution
|
|
270
|
+
Resolution used to scan the slide (10x, 20x, 40x). Default is 40x.
|
|
257
271
|
|
|
258
|
-
|
|
259
|
-
|
|
272
|
+
pil
|
|
273
|
+
If present, use Pillow to load the image instead of Bio-Formats. Pillow is
|
|
274
|
+
faster, but works only on common image types (png, jpeg, etc.).
|
|
260
275
|
|
|
261
|
-
|
|
262
|
-
|
|
276
|
+
slim
|
|
277
|
+
If present, return only the refined segmentation result image.
|
|
263
278
|
|
|
264
|
-
|
|
265
|
-
|
|
279
|
+
nopost
|
|
280
|
+
If present, do not perform postprocessing (returns only inferred images).
|
|
266
281
|
|
|
267
|
-
|
|
268
|
-
|
|
282
|
+
prob_thresh
|
|
283
|
+
Probability threshold used in postprocessing the inferred segmentation map
|
|
284
|
+
image. The segmentation map value must be above this value in order for a
|
|
285
|
+
pixel to be included in the final cell segmentation. Valid values are an
|
|
286
|
+
integer in the range 0-254. Default is 150.
|
|
287
|
+
|
|
288
|
+
size_thresh
|
|
289
|
+
Lower threshold for size gating the cells in postprocessing. Segmented
|
|
290
|
+
cells must have more pixels than this value in order to be included in the
|
|
291
|
+
final cell segmentation. Valid values are 0, a positive integer, or 'auto'.
|
|
292
|
+
'Auto' will try to automatically determine this lower bound for size gating
|
|
293
|
+
based on the distribution of detected cell sizes. Default is 'auto'.
|
|
294
|
+
|
|
295
|
+
size_thresh_upper
|
|
296
|
+
Upper threshold for size gating the cells in postprocessing. Segmented
|
|
297
|
+
cells must have less pixels that this value in order to be included in the
|
|
298
|
+
final cell segmentation. Valid values are a positive integer or 'none'.
|
|
299
|
+
'None' will use no upper threshold in size gating. Default is 'none'.
|
|
300
|
+
|
|
301
|
+
marker_thresh
|
|
302
|
+
Threshold for the effect that the inferred marker image will have on the
|
|
303
|
+
postprocessing classification of cells as positive. If any corresponding
|
|
304
|
+
pixel in the marker image for a cell is above this threshold, the cell will
|
|
305
|
+
be classified as being positive regardless of the values from the inferred
|
|
306
|
+
segmentation image. Valid values are an integer in the range 0-255, 'none',
|
|
307
|
+
or 'auto'. 'None' will not use the marker image during classification.
|
|
308
|
+
'Auto' will automatically determine a threshold from the marker image.
|
|
309
|
+
Default is 'auto'.
|
|
269
310
|
```
|
|
270
311
|
|
|
271
312
|
For example, in Python:
|
|
@@ -283,15 +324,118 @@ from PIL import Image
|
|
|
283
324
|
images_dir = './Sample_Large_Tissues'
|
|
284
325
|
filename = 'ROI_1.png'
|
|
285
326
|
|
|
327
|
+
root = os.path.splitext(filename)[0]
|
|
328
|
+
|
|
286
329
|
res = requests.post(
|
|
287
330
|
url='https://deepliif.org/api/infer',
|
|
288
331
|
files={
|
|
289
|
-
'img': open(f'{images_dir}/{filename}', 'rb')
|
|
332
|
+
'img': open(f'{images_dir}/{filename}', 'rb'),
|
|
290
333
|
},
|
|
291
|
-
# optional param that can be 10x, 20x, or 40x (default)
|
|
292
334
|
params={
|
|
293
|
-
'resolution': '40x'
|
|
294
|
-
}
|
|
335
|
+
'resolution': '40x',
|
|
336
|
+
},
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
data = res.json()
|
|
340
|
+
|
|
341
|
+
def b64_to_pil(b):
|
|
342
|
+
return Image.open(BytesIO(base64.b64decode(b.encode())))
|
|
343
|
+
|
|
344
|
+
for name, img in data['images'].items():
|
|
345
|
+
with open(f'{images_dir}/{root}_{name}.png', 'wb') as f:
|
|
346
|
+
b64_to_pil(img).save(f, format='PNG')
|
|
347
|
+
|
|
348
|
+
with open(f'{images_dir}/{root}_scoring.json', 'w') as f:
|
|
349
|
+
json.dump(data['scoring'], f, indent=2)
|
|
350
|
+
print(json.dumps(data['scoring'], indent=2))
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
If you have previously run DeepLIIF on an image and want to postprocess it with different thresholds, the postprocessing routine can be called directly using the previously inferred results:
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
POST /api/postprocess
|
|
357
|
+
|
|
358
|
+
File Parameters:
|
|
359
|
+
|
|
360
|
+
img (required)
|
|
361
|
+
Image on which DeepLIIF was run.
|
|
362
|
+
|
|
363
|
+
seg_img (required)
|
|
364
|
+
Inferred segmentation image previously generated by DeepLIIF.
|
|
365
|
+
|
|
366
|
+
marker_img (optional)
|
|
367
|
+
Inferred marker image previously generated by DeepLIIF. If this is
|
|
368
|
+
omitted, then the marker image will not be used in classification.
|
|
369
|
+
|
|
370
|
+
Query String Parameters:
|
|
371
|
+
|
|
372
|
+
resolution
|
|
373
|
+
Resolution used to scan the slide (10x, 20x, 40x). Default is 40x.
|
|
374
|
+
|
|
375
|
+
pil
|
|
376
|
+
If present, use Pillow to load the original image instead of Bio-Formats.
|
|
377
|
+
Pillow is faster, but works only on common image types (png, jpeg, etc.).
|
|
378
|
+
Pillow is always used to open the seg_img and marker_img files.
|
|
379
|
+
|
|
380
|
+
prob_thresh
|
|
381
|
+
Probability threshold used in postprocessing the inferred segmentation map
|
|
382
|
+
image. The segmentation map value must be above this value in order for a
|
|
383
|
+
pixel to be included in the final cell segmentation. Valid values are an
|
|
384
|
+
integer in the range 0-254. Default is 150.
|
|
385
|
+
|
|
386
|
+
size_thresh
|
|
387
|
+
Lower threshold for size gating the cells in postprocessing. Segmented
|
|
388
|
+
cells must have more pixels than this value in order to be included in the
|
|
389
|
+
final cell segmentation. Valid values are 0, a positive integer, or 'auto'.
|
|
390
|
+
'Auto' will try to automatically determine this lower bound for size gating
|
|
391
|
+
based on the distribution of detected cell sizes. Default is 'auto'.
|
|
392
|
+
|
|
393
|
+
size_thresh_upper
|
|
394
|
+
Upper threshold for size gating the cells in postprocessing. Segmented
|
|
395
|
+
cells must have less pixels that this value in order to be included in the
|
|
396
|
+
final cell segmentation. Valid values are a positive integer or 'none'.
|
|
397
|
+
'None' will use no upper threshold in size gating. Default is 'none'.
|
|
398
|
+
|
|
399
|
+
marker_thresh
|
|
400
|
+
Threshold for the effect that the inferred marker image will have on the
|
|
401
|
+
postprocessing classification of cells as positive. If any corresponding
|
|
402
|
+
pixel in the marker image for a cell is above this threshold, the cell will
|
|
403
|
+
be classified as being positive regardless of the values from the inferred
|
|
404
|
+
segmentation image. Valid values are an integer in the range 0-255, 'none',
|
|
405
|
+
or 'auto'. 'None' will not use the marker image during classification.
|
|
406
|
+
'Auto' will automatically determine a threshold from the marker image.
|
|
407
|
+
Default is 'auto'. (If marker_img is not supplied, this has no effect.)
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
For example, in Python:
|
|
411
|
+
|
|
412
|
+
```python
|
|
413
|
+
import os
|
|
414
|
+
import json
|
|
415
|
+
import base64
|
|
416
|
+
from io import BytesIO
|
|
417
|
+
|
|
418
|
+
import requests
|
|
419
|
+
from PIL import Image
|
|
420
|
+
|
|
421
|
+
# Use the sample images from the main DeepLIIF repo
|
|
422
|
+
images_dir = './Sample_Large_Tissues'
|
|
423
|
+
filename = 'ROI_1.png'
|
|
424
|
+
|
|
425
|
+
root = os.path.splitext(filename)[0]
|
|
426
|
+
|
|
427
|
+
res = requests.post(
|
|
428
|
+
url='https://deepliif.org/api/infer',
|
|
429
|
+
files={
|
|
430
|
+
'img': open(f'{images_dir}/{filename}', 'rb'),
|
|
431
|
+
'seg_img': open(f'{images_dir}/{root}_Seg.png', 'rb'),
|
|
432
|
+
'marker_img': open(f'{images_dir}/{root}_Marker.png', 'rb'),
|
|
433
|
+
},
|
|
434
|
+
params={
|
|
435
|
+
'resolution': '40x',
|
|
436
|
+
'pil': True,
|
|
437
|
+
'size_thresh': 250,
|
|
438
|
+
},
|
|
295
439
|
)
|
|
296
440
|
|
|
297
441
|
data = res.json()
|
|
@@ -300,10 +444,11 @@ def b64_to_pil(b):
|
|
|
300
444
|
return Image.open(BytesIO(base64.b64decode(b.encode())))
|
|
301
445
|
|
|
302
446
|
for name, img in data['images'].items():
|
|
303
|
-
|
|
304
|
-
with open(output_filepath, 'wb') as f:
|
|
447
|
+
with open(f'{images_dir}/{root}_{name}.png', 'wb') as f:
|
|
305
448
|
b64_to_pil(img).save(f, format='PNG')
|
|
306
449
|
|
|
450
|
+
with open(f'{images_dir}/{root}_scoring.json', 'w') as f:
|
|
451
|
+
json.dump(data['scoring'], f, indent=2)
|
|
307
452
|
print(json.dumps(data['scoring'], indent=2))
|
|
308
453
|
```
|
|
309
454
|
|
|
@@ -40,6 +40,9 @@ segmentation.*
|
|
|
40
40
|
|
|
41
41
|
© This code is made available for non-commercial academic purposes.
|
|
42
42
|
|
|
43
|
+

|
|
44
|
+
[](https://pepy.tech/project/deepliif?&left_text=totalusers)
|
|
45
|
+
|
|
43
46
|
*Overview of DeepLIIF pipeline and sample input IHCs (different
|
|
44
47
|
brown/DAB markers -- BCL2, BCL6, CD10, CD3/CD8, Ki67) with corresponding DeepLIIF-generated hematoxylin/mpIF modalities
|
|
45
48
|
and classified (positive (red) and negative (blue) cell) segmentation masks. (a) Overview of DeepLIIF. Given an IHC
|
|
@@ -111,7 +114,7 @@ deepliif prepare-training-data --input-dir /path/to/input/images
|
|
|
111
114
|
To train a model:
|
|
112
115
|
```
|
|
113
116
|
deepliif train --dataroot /path/to/input/images
|
|
114
|
-
|
|
117
|
+
--name Model_Name
|
|
115
118
|
```
|
|
116
119
|
or
|
|
117
120
|
```
|
|
@@ -157,7 +160,7 @@ The installed `deepliif` uses Dask to perform inference on the input IHC images.
|
|
|
157
160
|
Before running the `test` command, the model files must be serialized using Torchscript.
|
|
158
161
|
To serialize the model files:
|
|
159
162
|
```
|
|
160
|
-
deepliif serialize --
|
|
163
|
+
deepliif serialize --model-dir /path/to/input/model/files
|
|
161
164
|
--output-dir /path/to/output/model/files
|
|
162
165
|
```
|
|
163
166
|
* By default, the model files are expected to be located in `DeepLIIF/model-server/DeepLIIF_Latest_Model`.
|
|
@@ -166,15 +169,17 @@ deepliif serialize --models-dir /path/to/input/model/files
|
|
|
166
169
|
## Testing
|
|
167
170
|
To test the model:
|
|
168
171
|
```
|
|
169
|
-
deepliif test --input-dir /path/to/input/images
|
|
170
|
-
--output-dir /path/to/output/images
|
|
171
|
-
--model-dir path/to/the/serialized/model
|
|
172
|
+
deepliif test --input-dir /path/to/input/images
|
|
173
|
+
--output-dir /path/to/output/images
|
|
174
|
+
--model-dir /path/to/the/serialized/model
|
|
172
175
|
--tile-size 512
|
|
173
176
|
```
|
|
174
177
|
or
|
|
175
178
|
```
|
|
176
|
-
python test.py --dataroot /path/to/input/images
|
|
177
|
-
--
|
|
179
|
+
python test.py --dataroot /path/to/input/images
|
|
180
|
+
--results_dir /path/to/output/images
|
|
181
|
+
--checkpoints_dir /path/to/model/files
|
|
182
|
+
--name Model_Name
|
|
178
183
|
```
|
|
179
184
|
* The latest version of the pretrained models can be downloaded [here](https://zenodo.org/record/4751737#.YKRTS0NKhH4).
|
|
180
185
|
* Before running test on images, the model files must be serialized as described above.
|
|
@@ -195,7 +200,7 @@ Based on the available GPU resources, the region-size can be changed.
|
|
|
195
200
|
```
|
|
196
201
|
deepliif test --input-dir /path/to/input/images
|
|
197
202
|
--output-dir /path/to/output/images
|
|
198
|
-
--model-dir path/to/the/serialized/model
|
|
203
|
+
--model-dir /path/to/the/serialized/model
|
|
199
204
|
--tile-size 512
|
|
200
205
|
--region-size 20000
|
|
201
206
|
```
|
|
@@ -236,25 +241,61 @@ If you don't have access to GPU or appropriate hardware and don't want to instal
|
|
|
236
241
|
|
|
237
242
|

|
|
238
243
|
|
|
239
|
-
|
|
240
|
-
|
|
244
|
+
## Cloud API Endpoints
|
|
245
|
+
|
|
246
|
+
DeepLIIF can also be accessed programmatically through an endpoint by posting a multipart-encoded request containing the original image file, along with optional parameters including postprocessing thresholds:
|
|
241
247
|
|
|
242
248
|
```
|
|
243
249
|
POST /api/infer
|
|
244
250
|
|
|
245
|
-
|
|
251
|
+
File Parameter:
|
|
252
|
+
|
|
253
|
+
img (required)
|
|
254
|
+
Image on which to run DeepLIIF.
|
|
255
|
+
|
|
256
|
+
Query String Parameters:
|
|
257
|
+
|
|
258
|
+
resolution
|
|
259
|
+
Resolution used to scan the slide (10x, 20x, 40x). Default is 40x.
|
|
246
260
|
|
|
247
|
-
|
|
248
|
-
|
|
261
|
+
pil
|
|
262
|
+
If present, use Pillow to load the image instead of Bio-Formats. Pillow is
|
|
263
|
+
faster, but works only on common image types (png, jpeg, etc.).
|
|
249
264
|
|
|
250
|
-
|
|
251
|
-
|
|
265
|
+
slim
|
|
266
|
+
If present, return only the refined segmentation result image.
|
|
252
267
|
|
|
253
|
-
|
|
254
|
-
|
|
268
|
+
nopost
|
|
269
|
+
If present, do not perform postprocessing (returns only inferred images).
|
|
255
270
|
|
|
256
|
-
|
|
257
|
-
|
|
271
|
+
prob_thresh
|
|
272
|
+
Probability threshold used in postprocessing the inferred segmentation map
|
|
273
|
+
image. The segmentation map value must be above this value in order for a
|
|
274
|
+
pixel to be included in the final cell segmentation. Valid values are an
|
|
275
|
+
integer in the range 0-254. Default is 150.
|
|
276
|
+
|
|
277
|
+
size_thresh
|
|
278
|
+
Lower threshold for size gating the cells in postprocessing. Segmented
|
|
279
|
+
cells must have more pixels than this value in order to be included in the
|
|
280
|
+
final cell segmentation. Valid values are 0, a positive integer, or 'auto'.
|
|
281
|
+
'Auto' will try to automatically determine this lower bound for size gating
|
|
282
|
+
based on the distribution of detected cell sizes. Default is 'auto'.
|
|
283
|
+
|
|
284
|
+
size_thresh_upper
|
|
285
|
+
Upper threshold for size gating the cells in postprocessing. Segmented
|
|
286
|
+
cells must have less pixels that this value in order to be included in the
|
|
287
|
+
final cell segmentation. Valid values are a positive integer or 'none'.
|
|
288
|
+
'None' will use no upper threshold in size gating. Default is 'none'.
|
|
289
|
+
|
|
290
|
+
marker_thresh
|
|
291
|
+
Threshold for the effect that the inferred marker image will have on the
|
|
292
|
+
postprocessing classification of cells as positive. If any corresponding
|
|
293
|
+
pixel in the marker image for a cell is above this threshold, the cell will
|
|
294
|
+
be classified as being positive regardless of the values from the inferred
|
|
295
|
+
segmentation image. Valid values are an integer in the range 0-255, 'none',
|
|
296
|
+
or 'auto'. 'None' will not use the marker image during classification.
|
|
297
|
+
'Auto' will automatically determine a threshold from the marker image.
|
|
298
|
+
Default is 'auto'.
|
|
258
299
|
```
|
|
259
300
|
|
|
260
301
|
For example, in Python:
|
|
@@ -272,15 +313,118 @@ from PIL import Image
|
|
|
272
313
|
images_dir = './Sample_Large_Tissues'
|
|
273
314
|
filename = 'ROI_1.png'
|
|
274
315
|
|
|
316
|
+
root = os.path.splitext(filename)[0]
|
|
317
|
+
|
|
275
318
|
res = requests.post(
|
|
276
319
|
url='https://deepliif.org/api/infer',
|
|
277
320
|
files={
|
|
278
|
-
'img': open(f'{images_dir}/{filename}', 'rb')
|
|
321
|
+
'img': open(f'{images_dir}/{filename}', 'rb'),
|
|
279
322
|
},
|
|
280
|
-
# optional param that can be 10x, 20x, or 40x (default)
|
|
281
323
|
params={
|
|
282
|
-
'resolution': '40x'
|
|
283
|
-
}
|
|
324
|
+
'resolution': '40x',
|
|
325
|
+
},
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
data = res.json()
|
|
329
|
+
|
|
330
|
+
def b64_to_pil(b):
|
|
331
|
+
return Image.open(BytesIO(base64.b64decode(b.encode())))
|
|
332
|
+
|
|
333
|
+
for name, img in data['images'].items():
|
|
334
|
+
with open(f'{images_dir}/{root}_{name}.png', 'wb') as f:
|
|
335
|
+
b64_to_pil(img).save(f, format='PNG')
|
|
336
|
+
|
|
337
|
+
with open(f'{images_dir}/{root}_scoring.json', 'w') as f:
|
|
338
|
+
json.dump(data['scoring'], f, indent=2)
|
|
339
|
+
print(json.dumps(data['scoring'], indent=2))
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
If you have previously run DeepLIIF on an image and want to postprocess it with different thresholds, the postprocessing routine can be called directly using the previously inferred results:
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
POST /api/postprocess
|
|
346
|
+
|
|
347
|
+
File Parameters:
|
|
348
|
+
|
|
349
|
+
img (required)
|
|
350
|
+
Image on which DeepLIIF was run.
|
|
351
|
+
|
|
352
|
+
seg_img (required)
|
|
353
|
+
Inferred segmentation image previously generated by DeepLIIF.
|
|
354
|
+
|
|
355
|
+
marker_img (optional)
|
|
356
|
+
Inferred marker image previously generated by DeepLIIF. If this is
|
|
357
|
+
omitted, then the marker image will not be used in classification.
|
|
358
|
+
|
|
359
|
+
Query String Parameters:
|
|
360
|
+
|
|
361
|
+
resolution
|
|
362
|
+
Resolution used to scan the slide (10x, 20x, 40x). Default is 40x.
|
|
363
|
+
|
|
364
|
+
pil
|
|
365
|
+
If present, use Pillow to load the original image instead of Bio-Formats.
|
|
366
|
+
Pillow is faster, but works only on common image types (png, jpeg, etc.).
|
|
367
|
+
Pillow is always used to open the seg_img and marker_img files.
|
|
368
|
+
|
|
369
|
+
prob_thresh
|
|
370
|
+
Probability threshold used in postprocessing the inferred segmentation map
|
|
371
|
+
image. The segmentation map value must be above this value in order for a
|
|
372
|
+
pixel to be included in the final cell segmentation. Valid values are an
|
|
373
|
+
integer in the range 0-254. Default is 150.
|
|
374
|
+
|
|
375
|
+
size_thresh
|
|
376
|
+
Lower threshold for size gating the cells in postprocessing. Segmented
|
|
377
|
+
cells must have more pixels than this value in order to be included in the
|
|
378
|
+
final cell segmentation. Valid values are 0, a positive integer, or 'auto'.
|
|
379
|
+
'Auto' will try to automatically determine this lower bound for size gating
|
|
380
|
+
based on the distribution of detected cell sizes. Default is 'auto'.
|
|
381
|
+
|
|
382
|
+
size_thresh_upper
|
|
383
|
+
Upper threshold for size gating the cells in postprocessing. Segmented
|
|
384
|
+
cells must have less pixels that this value in order to be included in the
|
|
385
|
+
final cell segmentation. Valid values are a positive integer or 'none'.
|
|
386
|
+
'None' will use no upper threshold in size gating. Default is 'none'.
|
|
387
|
+
|
|
388
|
+
marker_thresh
|
|
389
|
+
Threshold for the effect that the inferred marker image will have on the
|
|
390
|
+
postprocessing classification of cells as positive. If any corresponding
|
|
391
|
+
pixel in the marker image for a cell is above this threshold, the cell will
|
|
392
|
+
be classified as being positive regardless of the values from the inferred
|
|
393
|
+
segmentation image. Valid values are an integer in the range 0-255, 'none',
|
|
394
|
+
or 'auto'. 'None' will not use the marker image during classification.
|
|
395
|
+
'Auto' will automatically determine a threshold from the marker image.
|
|
396
|
+
Default is 'auto'. (If marker_img is not supplied, this has no effect.)
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
For example, in Python:
|
|
400
|
+
|
|
401
|
+
```python
|
|
402
|
+
import os
|
|
403
|
+
import json
|
|
404
|
+
import base64
|
|
405
|
+
from io import BytesIO
|
|
406
|
+
|
|
407
|
+
import requests
|
|
408
|
+
from PIL import Image
|
|
409
|
+
|
|
410
|
+
# Use the sample images from the main DeepLIIF repo
|
|
411
|
+
images_dir = './Sample_Large_Tissues'
|
|
412
|
+
filename = 'ROI_1.png'
|
|
413
|
+
|
|
414
|
+
root = os.path.splitext(filename)[0]
|
|
415
|
+
|
|
416
|
+
res = requests.post(
|
|
417
|
+
url='https://deepliif.org/api/infer',
|
|
418
|
+
files={
|
|
419
|
+
'img': open(f'{images_dir}/{filename}', 'rb'),
|
|
420
|
+
'seg_img': open(f'{images_dir}/{root}_Seg.png', 'rb'),
|
|
421
|
+
'marker_img': open(f'{images_dir}/{root}_Marker.png', 'rb'),
|
|
422
|
+
},
|
|
423
|
+
params={
|
|
424
|
+
'resolution': '40x',
|
|
425
|
+
'pil': True,
|
|
426
|
+
'size_thresh': 250,
|
|
427
|
+
},
|
|
284
428
|
)
|
|
285
429
|
|
|
286
430
|
data = res.json()
|
|
@@ -289,10 +433,11 @@ def b64_to_pil(b):
|
|
|
289
433
|
return Image.open(BytesIO(base64.b64decode(b.encode())))
|
|
290
434
|
|
|
291
435
|
for name, img in data['images'].items():
|
|
292
|
-
|
|
293
|
-
with open(output_filepath, 'wb') as f:
|
|
436
|
+
with open(f'{images_dir}/{root}_{name}.png', 'wb') as f:
|
|
294
437
|
b64_to_pil(img).save(f, format='PNG')
|
|
295
438
|
|
|
439
|
+
with open(f'{images_dir}/{root}_scoring.json', 'w') as f:
|
|
440
|
+
json.dump(data['scoring'], f, indent=2)
|
|
296
441
|
print(json.dumps(data['scoring'], indent=2))
|
|
297
442
|
```
|
|
298
443
|
|