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.
Files changed (44) hide show
  1. {deepliif-1.1.9/deepliif.egg-info → deepliif-1.1.10}/PKG-INFO +171 -26
  2. {deepliif-1.1.9 → deepliif-1.1.10}/README.md +170 -25
  3. {deepliif-1.1.9 → deepliif-1.1.10}/cli.py +49 -42
  4. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/aligned_dataset.py +17 -0
  5. deepliif-1.1.10/deepliif/models/SDG_model.py +189 -0
  6. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/__init__.py +109 -44
  7. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/__init__.py +62 -29
  8. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/__init__.py +22 -0
  9. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/util.py +17 -1
  10. {deepliif-1.1.9 → deepliif-1.1.10/deepliif.egg-info}/PKG-INFO +171 -26
  11. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/SOURCES.txt +1 -0
  12. {deepliif-1.1.9 → deepliif-1.1.10}/setup.cfg +1 -1
  13. {deepliif-1.1.9 → deepliif-1.1.10}/setup.py +1 -1
  14. {deepliif-1.1.9 → deepliif-1.1.10}/tests/test_cli_inference.py +170 -0
  15. {deepliif-1.1.9 → deepliif-1.1.10}/tests/test_cli_serialize.py +1 -1
  16. {deepliif-1.1.9 → deepliif-1.1.10}/LICENSE.md +0 -0
  17. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/__init__.py +0 -0
  18. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/__init__.py +0 -0
  19. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/base_dataset.py +0 -0
  20. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/colorization_dataset.py +0 -0
  21. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/image_folder.py +0 -0
  22. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/single_dataset.py +0 -0
  23. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/template_dataset.py +0 -0
  24. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/data/unaligned_dataset.py +0 -0
  25. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/DeepLIIFExt_model.py +0 -0
  26. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/DeepLIIF_model.py +0 -0
  27. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/base_model.py +0 -0
  28. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/models/networks.py +0 -0
  29. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/base_options.py +0 -0
  30. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/processing_options.py +0 -0
  31. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/test_options.py +0 -0
  32. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/options/train_options.py +0 -0
  33. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/postprocessing.py +0 -0
  34. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/train.py +0 -0
  35. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/get_data.py +0 -0
  36. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/html.py +0 -0
  37. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/image_pool.py +0 -0
  38. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif/util/visualizer.py +0 -0
  39. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/dependency_links.txt +0 -0
  40. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/entry_points.txt +0 -0
  41. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/requires.txt +0 -0
  42. {deepliif-1.1.9 → deepliif-1.1.10}/deepliif.egg-info/top_level.txt +0 -0
  43. {deepliif-1.1.9 → deepliif-1.1.10}/tests/test_args.py +0 -0
  44. {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.9
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
+ ![Version](https://img.shields.io/static/v1?label=latest&message=v1.1.9&color=darkgreen)
55
+ [![Total Downloads](https://static.pepy.tech/personalized-badge/deepliif?period=total&units=international_system&left_color=grey&right_color=blue&left_text=total%20downloads)](https://pepy.tech/project/deepliif?&left_text=totalusers)
56
+
54
57
  ![overview_image](./images/overview.png)*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
- --name Model_Name
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 --models-dir /path/to/input/model/files
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
- --name Model_Name
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
  ![DeepLIIF Website Demo](images/deepliif-website-demo-03.gif)
249
254
 
250
- DeepLIIF can also be accessed programmatically through an endpoint by posting a multipart-encoded request
251
- containing the original image file:
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
- Parameters
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
- img (required)
259
- file: image to run the models on
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
- resolution
262
- string: resolution used to scan the slide (10x, 20x, 40x), defaults to 40x
276
+ slim
277
+ If present, return only the refined segmentation result image.
263
278
 
264
- pil
265
- boolean: if true, use PIL.Image.open() to load the image, instead of python-bioformats
279
+ nopost
280
+ If present, do not perform postprocessing (returns only inferred images).
266
281
 
267
- slim
268
- boolean: if true, return only the segmentation result image
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
- output_filepath = f'{images_dir}/{os.path.splitext(filename)[0]}_{name}.png'
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
+ ![Version](https://img.shields.io/static/v1?label=latest&message=v1.1.9&color=darkgreen)
44
+ [![Total Downloads](https://static.pepy.tech/personalized-badge/deepliif?period=total&units=international_system&left_color=grey&right_color=blue&left_text=total%20downloads)](https://pepy.tech/project/deepliif?&left_text=totalusers)
45
+
43
46
  ![overview_image](./images/overview.png)*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
- --name Model_Name
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 --models-dir /path/to/input/model/files
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
- --name Model_Name
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
  ![DeepLIIF Website Demo](images/deepliif-website-demo-03.gif)
238
243
 
239
- DeepLIIF can also be accessed programmatically through an endpoint by posting a multipart-encoded request
240
- containing the original image file:
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
- Parameters
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
- img (required)
248
- file: image to run the models on
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
- resolution
251
- string: resolution used to scan the slide (10x, 20x, 40x), defaults to 40x
265
+ slim
266
+ If present, return only the refined segmentation result image.
252
267
 
253
- pil
254
- boolean: if true, use PIL.Image.open() to load the image, instead of python-bioformats
268
+ nopost
269
+ If present, do not perform postprocessing (returns only inferred images).
255
270
 
256
- slim
257
- boolean: if true, return only the segmentation result image
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
- output_filepath = f'{images_dir}/{os.path.splitext(filename)[0]}_{name}.png'
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