biapy 3.3.6__tar.gz → 3.3.7__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 (146) hide show
  1. {biapy-3.3.6/biapy.egg-info → biapy-3.3.7}/PKG-INFO +1 -1
  2. {biapy-3.3.6 → biapy-3.3.7}/biapy/_biapy.py +17 -6
  3. {biapy-3.3.6 → biapy-3.3.7}/biapy/config/config.py +4 -3
  4. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/data_2D_manipulation.py +2 -2
  5. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/data_3D_manipulation.py +1 -1
  6. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/augmentors.py +22 -7
  7. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/pair_base_data_generator.py +81 -61
  8. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/single_base_data_generator.py +1 -2
  9. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/post_processing/post_processing.py +45 -7
  10. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/pre_processing.py +25 -4
  11. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/base_workflow.py +71 -69
  12. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/check_configuration.py +11 -9
  13. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/classification.py +1 -1
  14. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/denoising.py +1 -1
  15. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/detection.py +2 -3
  16. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/instance_seg.py +219 -67
  17. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/metrics.py +187 -52
  18. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/self_supervised.py +1 -1
  19. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/semantic_seg.py +2 -3
  20. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/super_resolution.py +1 -1
  21. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/attention_unet.py +18 -4
  22. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/multiresunet.py +16 -2
  23. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/resunet++.py +16 -2
  24. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/resunet.py +16 -2
  25. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/seunet.py +17 -3
  26. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/unet.py +18 -4
  27. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/unetr.py +16 -2
  28. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/util.py +3 -6
  29. {biapy-3.3.6 → biapy-3.3.7/biapy.egg-info}/PKG-INFO +1 -1
  30. {biapy-3.3.6 → biapy-3.3.7}/pyproject.toml +1 -1
  31. {biapy-3.3.6 → biapy-3.3.7}/setup.py +1 -1
  32. {biapy-3.3.6 → biapy-3.3.7}/.gitignore +0 -0
  33. {biapy-3.3.6 → biapy-3.3.7}/CODE_OF_CONDUCT.md +0 -0
  34. {biapy-3.3.6 → biapy-3.3.7}/LICENSE.md +0 -0
  35. {biapy-3.3.6 → biapy-3.3.7}/README.md +0 -0
  36. {biapy-3.3.6 → biapy-3.3.7}/biapy/__init__.py +0 -0
  37. {biapy-3.3.6 → biapy-3.3.7}/biapy/config/__init__.py +0 -0
  38. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/__init__.py +0 -0
  39. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/__init__.py +0 -0
  40. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/pair_data_2D_generator.py +0 -0
  41. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/pair_data_3D_generator.py +0 -0
  42. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/single_data_2D_generator.py +0 -0
  43. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/single_data_3D_generator.py +0 -0
  44. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/test_pair_data_generators.py +0 -0
  45. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/generators/test_single_data_generator.py +0 -0
  46. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/post_processing/__init__.py +0 -0
  47. {biapy-3.3.6 → biapy-3.3.7}/biapy/data/post_processing/smooth_tiled_predictions.py +0 -0
  48. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/__init__.py +0 -0
  49. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/schedulers/warmup_cosine_decay.py +0 -0
  50. {biapy-3.3.6 → biapy-3.3.7}/biapy/engine/train_engine.py +0 -0
  51. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/__init__.py +0 -0
  52. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/blocks.py +0 -0
  53. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/dfcan.py +0 -0
  54. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/edsr.py +0 -0
  55. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/efficientnet.py +0 -0
  56. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/mae.py +0 -0
  57. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/rcan.py +0 -0
  58. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/simple_cnn.py +0 -0
  59. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/tr_layers.py +0 -0
  60. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/vit.py +0 -0
  61. {biapy-3.3.6 → biapy-3.3.7}/biapy/models/wdsr.py +0 -0
  62. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/callbacks.py +0 -0
  63. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/env/Dockerfile +0 -0
  64. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/env/Dockerfile_CUDA10.2 +0 -0
  65. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/env/create_docker_image.sh +0 -0
  66. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/matching.py +0 -0
  67. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/misc.py +0 -0
  68. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/calculate_detection_metrics.py +0 -0
  69. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/calculate_metrics_3D.py +0 -0
  70. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/create_probability_csv.py +0 -0
  71. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/crop_2D_dataset.py +0 -0
  72. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/crop_3D_dataset.py +0 -0
  73. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/crop_and_discard_3D_dataset.py +0 -0
  74. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/detection_plots.py +0 -0
  75. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/detection_probs_to_points.py +0 -0
  76. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/fill_holes_in_seg_masks.py +0 -0
  77. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/filter_close_points.py +0 -0
  78. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/from_class_csv_to_folders.py +0 -0
  79. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/h5_to_tif.py +0 -0
  80. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/h5_to_zarr.py +0 -0
  81. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/merge_dataset_channels.py +0 -0
  82. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/order_axes.py +0 -0
  83. {biapy-3.3.6 → biapy-3.3.7}/biapy/utils/scripts/tif_to_h5.py +0 -0
  84. {biapy-3.3.6 → biapy-3.3.7}/biapy.egg-info/SOURCES.txt +0 -0
  85. {biapy-3.3.6 → biapy-3.3.7}/biapy.egg-info/dependency_links.txt +0 -0
  86. {biapy-3.3.6 → biapy-3.3.7}/biapy.egg-info/requires.txt +0 -0
  87. {biapy-3.3.6 → biapy-3.3.7}/biapy.egg-info/top_level.txt +0 -0
  88. {biapy-3.3.6 → biapy-3.3.7}/img/BiaPy-Euro-BioImaging-youtube.png +0 -0
  89. {biapy-3.3.6 → biapy-3.3.7}/img/BiaPy-workflow-readme.svg +0 -0
  90. {biapy-3.3.6 → biapy-3.3.7}/img/BiaPy_GUI_main_page.png +0 -0
  91. {biapy-3.3.6 → biapy-3.3.7}/img/BiaPy_presentation_and_demo_at_RTmfm.jpg +0 -0
  92. {biapy-3.3.6 → biapy-3.3.7}/img/MitoEM_teaser_cable_length_split.png +0 -0
  93. {biapy-3.3.6 → biapy-3.3.7}/img/biapy_logo.png +0 -0
  94. {biapy-3.3.6 → biapy-3.3.7}/img/complex_MOAS.png +0 -0
  95. {biapy-3.3.6 → biapy-3.3.7}/img/cyst_instance_prediction.gif +0 -0
  96. {biapy-3.3.6 → biapy-3.3.7}/img/cyst_sample.gif +0 -0
  97. {biapy-3.3.6 → biapy-3.3.7}/img/domain_EM.jpg +0 -0
  98. {biapy-3.3.6 → biapy-3.3.7}/img/halo_instances.png +0 -0
  99. {biapy-3.3.6 → biapy-3.3.7}/img/unet_attn_stable.png +0 -0
  100. {biapy-3.3.6 → biapy-3.3.7}/img/wound_diagram_VQVAE.png +0 -0
  101. {biapy-3.3.6 → biapy-3.3.7}/main.py +0 -0
  102. {biapy-3.3.6 → biapy-3.3.7}/notebooks/BiaPy_Inference.ipynb +0 -0
  103. {biapy-3.3.6 → biapy-3.3.7}/notebooks/classification/BiaPy_2D_Classification.ipynb +0 -0
  104. {biapy-3.3.6 → biapy-3.3.7}/notebooks/classification/BiaPy_2D_Classification_Butterfly.ipynb +0 -0
  105. {biapy-3.3.6 → biapy-3.3.7}/notebooks/classification/BiaPy_3D_Classification.ipynb +0 -0
  106. {biapy-3.3.6 → biapy-3.3.7}/notebooks/denoising/BiaPy_2D_Denoising.ipynb +0 -0
  107. {biapy-3.3.6 → biapy-3.3.7}/notebooks/denoising/BiaPy_3D_Denoising.ipynb +0 -0
  108. {biapy-3.3.6 → biapy-3.3.7}/notebooks/detection/BiaPy_2D_Detection.ipynb +0 -0
  109. {biapy-3.3.6 → biapy-3.3.7}/notebooks/detection/BiaPy_3D_Detection.ipynb +0 -0
  110. {biapy-3.3.6 → biapy-3.3.7}/notebooks/instance_segmentation/BiaPy_2D_Instance_Segmentation.ipynb +0 -0
  111. {biapy-3.3.6 → biapy-3.3.7}/notebooks/instance_segmentation/BiaPy_3D_Instance_Segmentation.ipynb +0 -0
  112. {biapy-3.3.6 → biapy-3.3.7}/notebooks/self-supervised/BiaPy_2D_Self_Supervision.ipynb +0 -0
  113. {biapy-3.3.6 → biapy-3.3.7}/notebooks/self-supervised/BiaPy_3D_Self_Supervision.ipynb +0 -0
  114. {biapy-3.3.6 → biapy-3.3.7}/notebooks/semantic_segmentation/BiaPy_2D_Semantic_Segmentation.ipynb +0 -0
  115. {biapy-3.3.6 → biapy-3.3.7}/notebooks/semantic_segmentation/BiaPy_3D_Semantic_Segmentation.ipynb +0 -0
  116. {biapy-3.3.6 → biapy-3.3.7}/notebooks/super-resolution/BiaPy_2D_Super_Resolution.ipynb +0 -0
  117. {biapy-3.3.6 → biapy-3.3.7}/notebooks/super-resolution/BiaPy_3D_Super_Resolution.ipynb +0 -0
  118. {biapy-3.3.6 → biapy-3.3.7}/setup.cfg +0 -0
  119. {biapy-3.3.6 → biapy-3.3.7}/templates/classification/2d_classification.yaml +0 -0
  120. {biapy-3.3.6 → biapy-3.3.7}/templates/classification/2d_classification_rgb.yaml +0 -0
  121. {biapy-3.3.6 → biapy-3.3.7}/templates/classification/3d_classification.yaml +0 -0
  122. {biapy-3.3.6 → biapy-3.3.7}/templates/denoising/2d_denoising.yaml +0 -0
  123. {biapy-3.3.6 → biapy-3.3.7}/templates/denoising/3d_denoising.yaml +0 -0
  124. {biapy-3.3.6 → biapy-3.3.7}/templates/detection/2d_detection.yaml +0 -0
  125. {biapy-3.3.6 → biapy-3.3.7}/templates/detection/3d_detection.yaml +0 -0
  126. {biapy-3.3.6 → biapy-3.3.7}/templates/instance_segmentation/2d_instance_segmentation.yaml +0 -0
  127. {biapy-3.3.6 → biapy-3.3.7}/templates/instance_segmentation/3d_instance_segmentation.yaml +0 -0
  128. {biapy-3.3.6 → biapy-3.3.7}/templates/instance_segmentation/CartoCell_paper/CartoCell - Inference workflow (Phase 5).ipynb +0 -0
  129. {biapy-3.3.6 → biapy-3.3.7}/templates/instance_segmentation/CartoCell_paper/CartoCell - Training workflow (Phase 2).ipynb +0 -0
  130. {biapy-3.3.6 → biapy-3.3.7}/templates/instance_segmentation/CartoCell_paper/cartocell_inference.yaml +0 -0
  131. {biapy-3.3.6 → biapy-3.3.7}/templates/instance_segmentation/CartoCell_paper/cartocell_training.yaml +0 -0
  132. {biapy-3.3.6 → biapy-3.3.7}/templates/instance_segmentation/CartoCell_paper/model_weights_cartocell.h5 +0 -0
  133. {biapy-3.3.6 → biapy-3.3.7}/templates/instance_segmentation/MitoEM_paper/mitoem.yaml +0 -0
  134. {biapy-3.3.6 → biapy-3.3.7}/templates/self-supervised/2d_self-supervised.yaml +0 -0
  135. {biapy-3.3.6 → biapy-3.3.7}/templates/self-supervised/3d_self-supervised.yaml +0 -0
  136. {biapy-3.3.6 → biapy-3.3.7}/templates/semantic_segmentation/2d_semantic_segmentation.yaml +0 -0
  137. {biapy-3.3.6 → biapy-3.3.7}/templates/semantic_segmentation/3d_semantic_segmentation.yaml +0 -0
  138. {biapy-3.3.6 → biapy-3.3.7}/templates/semantic_segmentation/stable_paper/semantic_segmentation_workflow.ipynb +0 -0
  139. {biapy-3.3.6 → biapy-3.3.7}/templates/sota_implementations/Casser_workflow.ipynb +0 -0
  140. {biapy-3.3.6 → biapy-3.3.7}/templates/sota_implementations/Cheng_2D_workflow.ipynb +0 -0
  141. {biapy-3.3.6 → biapy-3.3.7}/templates/sota_implementations/Cheng_3D_workflow.ipynb +0 -0
  142. {biapy-3.3.6 → biapy-3.3.7}/templates/sota_implementations/Oztel_workflow.ipynb +0 -0
  143. {biapy-3.3.6 → biapy-3.3.7}/templates/sota_implementations/Xiao_workflow.ipynb +0 -0
  144. {biapy-3.3.6 → biapy-3.3.7}/templates/super-resolution/2d_super-resolution.yaml +0 -0
  145. {biapy-3.3.6 → biapy-3.3.7}/templates/super-resolution/2d_super-resolution_rgb.yaml +0 -0
  146. {biapy-3.3.6 → biapy-3.3.7}/templates/super-resolution/3d_super-resolution.yaml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: biapy
3
- Version: 3.3.6
3
+ Version: 3.3.7
4
4
  Summary: BiaPy: Bioimage analysis pipelines in Python
5
5
  Home-page: https://github.com/BiaPyX/BiaPy
6
6
  Author: BiaPy Contributors
@@ -219,12 +219,23 @@ class BiaPy():
219
219
  # Check if BiaPy has been run so some of the variables have been created
220
220
  if not self.workflow.model_prepared:
221
221
  raise ValueError("You need first to call prepare_model(), train(), test() or run_job() functions so the model can be built")
222
- if 'test_input' in bmz_cfg and bmz_cfg['test_input'] is None and self.workflow.bmz_test_input is None:
223
- raise ValueError("No bmz_cfg['test_input'] available. You can: 1) provide it using bmz_config['test_input'] "
224
- "or run the training phase, by calling train() or run_job() functions.")
225
- if 'test_output' in bmz_cfg and bmz_cfg['test_output'] is None and self.workflow.bmz_test_output is None:
226
- raise ValueError("No bmz_cfg['test_output'] available. You can: 1) provide it using bmz_config['test_output'] "
227
- "or run the training phase, by calling train() or run_job() functions.")
222
+ error = False
223
+ if self.workflow.bmz_test_input is None:
224
+ if 'test_input' not in bmz_cfg:
225
+ error = True
226
+ elif bmz_cfg['test_input'] is None:
227
+ error = True
228
+ if error:
229
+ raise ValueError("No bmz_cfg['test_input'] available. You can: 1) provide it using bmz_config['test_input'] "
230
+ "or run the training phase, by calling train() or run_job() functions.")
231
+ if self.workflow.bmz_test_output is None:
232
+ if 'test_output' not in bmz_cfg:
233
+ error = True
234
+ elif bmz_cfg['test_output'] is None:
235
+ error = True
236
+ if error:
237
+ raise ValueError("No bmz_cfg['test_output'] available. You can: 1) provide it using bmz_config['test_output'] "
238
+ "or run the training phase, by calling train() or run_job() functions.")
228
239
 
229
240
  # Check BMZ dictionary keys and values
230
241
  if bmz_cfg['description'] == "":
@@ -24,7 +24,7 @@ class Config:
24
24
  # Do not set it as its value will be calculated based in --gpu input arg
25
25
  _C.SYSTEM.NUM_GPUS = 0
26
26
 
27
- # Math seed
27
+ # Math seed to generate random numbers. Used to ensure reproducibility in the results.
28
28
  _C.SYSTEM.SEED = 0
29
29
  # Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.
30
30
  _C.SYSTEM.PIN_MEM = True
@@ -322,7 +322,7 @@ class Config:
322
322
  # Test data resolution. Need to be provided in (z,y,x) order. Only applies when _C.PROBLEM.TYPE = 'DETECTION' now.
323
323
  _C.DATA.TEST.RESOLUTION = (-1,)
324
324
  # Whether to apply argmax to the predicted images
325
- _C.DATA.TEST.ARGMAX_TO_OUTPUT = False
325
+ _C.DATA.TEST.ARGMAX_TO_OUTPUT = True
326
326
 
327
327
  # Validation
328
328
  _C.DATA.VAL = CN()
@@ -407,7 +407,8 @@ class Config:
407
407
  # “no change” and 0.5 denotes “half of the axis size”.
408
408
  _C.AUGMENTOR.SHIFT_RANGE = (0.1, 0.2)
409
409
  # How to fill up the new values created with affine transformations (rotations, shear, shift and zoom).
410
- # Same meaning as in skimage (and numpy.pad()): 'constant', 'edge', 'symmetric', 'reflect' and 'wrap'
410
+ # Same meaning as in scipy: 'reflect', grid-'mirror', 'constant', 'grid-constant', 'nearest', 'mirror',
411
+ # 'grid-wrap' and 'wrap'.
411
412
  _C.AUGMENTOR.AFFINE_MODE = 'constant'
412
413
  # Make vertical flips
413
414
  _C.AUGMENTOR.VFLIP = False
@@ -685,10 +685,10 @@ def merge_data_with_overlap(data, original_shape, data_mask=None, overlap=(0,0),
685
685
 
686
686
  merged_data = np.zeros((original_shape), dtype=np.float32)
687
687
  if data_mask is not None:
688
- merged_data_mask = np.zeros((original_shape), dtype=np.float32)
688
+ merged_data_mask = np.zeros((original_shape[:-1]+(data_mask.shape[-1],)), dtype=np.float32)
689
689
  data_mask = data_mask[:, padding[0]:data_mask.shape[1]-padding[0], padding[1]:data_mask.shape[2]-padding[1]]
690
690
 
691
- ov_map_counter = np.zeros(original_shape, dtype=np.int32)
691
+ ov_map_counter = np.zeros(original_shape[:-1]+(1,), dtype=np.int32)
692
692
  if out_dir is not None:
693
693
  crop_grid = np.zeros(original_shape[1:], dtype=np.int32)
694
694
 
@@ -616,7 +616,7 @@ def merge_3D_data_with_overlap(data, orig_vol_shape, data_mask=None, overlap=(0,
616
616
  padding[1]:data_mask.shape[2]-padding[1],
617
617
  padding[2]:data_mask.shape[3]-padding[2], :]
618
618
  merged_data_mask = np.zeros(orig_vol_shape[:3]+(data_mask.shape[-1],), dtype=np.float32)
619
- ov_map_counter = np.zeros((orig_vol_shape), dtype=np.uint16)
619
+ ov_map_counter = np.zeros((orig_vol_shape[:-1]+(1,)), dtype=np.uint16)
620
620
 
621
621
  # Calculate overlapping variables
622
622
  overlap_z = 1 if overlap[0] == 0 else 1-overlap[0]
@@ -3,10 +3,11 @@ import random
3
3
  import math
4
4
  import numpy as np
5
5
  from PIL import Image
6
- from skimage.transform import resize, rotate
6
+ from skimage.transform import resize
7
7
  from skimage.draw import line
8
8
  from scipy.ndimage.measurements import label
9
9
  from scipy.ndimage.morphology import binary_dilation
10
+ from scipy.ndimage import rotate
10
11
 
11
12
 
12
13
  def cutout(img, mask, channels, z_size, nb_iterations=(1,3), size=(0.2,0.4), cval=0, res_relation=(1,1), apply_to_mask=False):
@@ -1500,7 +1501,7 @@ def resize_img(img, shape):
1500
1501
  return resize(img, shape, order=1, mode='reflect', clip=True, preserve_range=True, anti_aliasing=True)
1501
1502
 
1502
1503
 
1503
- def rotation(img, mask=None, angles=[], mode="reflect", mask_type='as_mask'):
1504
+ def rotation(img, mask=None, heat=None, angles=[], mode="reflect", mask_type='as_mask'):
1504
1505
  """
1505
1506
  Apply a rotation to input ``image`` and ``mask`` (if provided).
1506
1507
 
@@ -1512,12 +1513,15 @@ def rotation(img, mask=None, angles=[], mode="reflect", mask_type='as_mask'):
1512
1513
  mask : 3D/4D Numpy array, optional
1513
1514
  Mask to rotate. E.g. ``(y, x, channels)`` for ``2D`` or ``(z, y, x, channels)`` for ``3D``.
1514
1515
 
1516
+ heat : 3D/4D Numpy array, optional
1517
+ Heatmap (float mask) to rotate. E.g. ``(y, x, channels)`` for ``2D`` or ``(z, y, x, channels)`` for ``3D``.
1518
+
1515
1519
  angles : List of ints, optional
1516
1520
  List of angles to choose the rotation to be made. E.g. [90,180,360].
1517
1521
 
1518
1522
  mode : str, optional
1519
- How to fill up the new values created. Options: ``constant``, ``edge``, ``symmetric``,
1520
- ``reflect`` and ``wrap``.
1523
+ How to fill up the new values created. Options: ``reflect``, ``grid-mirror``,
1524
+ ``constant``, ``grid-constant``, ``nearest``, ``mirror``, ``grid-wrap``, ``wrap``.
1521
1525
 
1522
1526
  mask_type : str, optional
1523
1527
  How ``mask`` is going to be treated. Options: ``as_mask``, ``as_image``. With ``as_mask``
@@ -1530,6 +1534,10 @@ def rotation(img, mask=None, angles=[], mode="reflect", mask_type='as_mask'):
1530
1534
 
1531
1535
  mask : 3D/4D Numpy array, optional
1532
1536
  Rotated mask. E.g. ``(y, x, channels)`` for ``2D`` or ``(z, y, x, channels)`` for ``3D``.
1537
+
1538
+ heat : 3D/4D Numpy array, optional
1539
+ Rotated heatmap. Returned if ``mask`` is provided. E.g. ``(y, x, channels)`` for ``2D`` or
1540
+ ``(z, y, x, channels)`` for ``3D``.
1533
1541
  """
1534
1542
 
1535
1543
  if len(angles) == 0:
@@ -1542,8 +1550,15 @@ def rotation(img, mask=None, angles=[], mode="reflect", mask_type='as_mask'):
1542
1550
  else:
1543
1551
  raise ValueError("Not a list/tuple provided in 'angles'")
1544
1552
 
1545
- mask_order = 0 if mask_type == 'as_mask' else 1
1553
+ img = rotate(img, angle=angle, mode=mode, reshape=False)
1554
+
1555
+ if mask is not None:
1556
+ mask_order = 0 if mask_type == 'as_mask' else 1
1557
+ mask = rotate(mask, angle=angle, order=mask_order, mode=mode, reshape=False)
1558
+ if heat is not None:
1559
+ heat = rotate(heat, angle=angle, mode=mode, reshape=False)
1546
1560
  if mask is None:
1547
- return rotate(img, angle, mode=mode)
1561
+ return img
1548
1562
  else:
1549
- return rotate(img, angle, mode=mode), rotate(mask.astype(np.float32), angle, order=mask_order, mode=mode)
1563
+ return img, mask, heat
1564
+
@@ -314,7 +314,7 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
314
314
  data must be the same on each epoch). Valid when ``random_crops_in_DA`` is set.
315
315
 
316
316
  n_classes : int, optional
317
- Number of classes. If ``> 1`` one-hot encoding will be done on the ground truth.
317
+ Number of classes.
318
318
 
319
319
  extra_data_factor : int, optional
320
320
  Factor to multiply the batches yielded in a epoch. It acts as if ``X`` and ``Y``` where concatenated
@@ -358,7 +358,7 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
358
358
  normalizeY : str, optional
359
359
  Whether Y is going to be normalized or not. Options: ``as_mask``, ``as_image``. With ``as_image`` the image will be
360
360
  treated as another image and not as a mask (for normalization and interpolation).
361
-
361
+
362
362
  instance_problem : bool, optional
363
363
  Advice the class that the workflow is of instance segmentation to divide the labels by channels.
364
364
 
@@ -473,9 +473,8 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
473
473
  self.Y = Y
474
474
  self.length = len(self.X)
475
475
 
476
- self.first_no_bin_channel = -1
477
- self.div_Y_on_load_bin_channels = False
478
- self.div_Y_on_load_no_bin_channels = False
476
+ self.channel_info = {}
477
+ self.no_bin_channel_found = False
479
478
  self.shape = shape
480
479
 
481
480
  # X data analysis
@@ -538,30 +537,41 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
538
537
 
539
538
  # Y data analysis
540
539
  if self.Y_provided:
541
- found = False
542
540
  # Loop over a few masks to ensure foreground class is present to decide normalization
543
541
  n_samples = len(self.data_mask_path) if not in_memory else len(self.Y)
542
+ self.channels_to_analize = -1
543
+ analized = False
544
+ print("Checking which channel of the mask needs normalization . . .")
544
545
  for i in range(n_samples):
545
546
  _, mask = self.load_sample(i)
546
547
  if self.normalizeY == 'as_mask':
547
- # Store wheter all channels of the gt are binary or not (i.e. distance transform channel)
548
- if not found and (mask.dtype is np.dtype(np.float32) or mask.dtype is np.dtype(np.float64)) and instance_problem:
549
- for j in range(mask.shape[-1]):
550
- if len(np.unique(mask[...,j])) > 2:
551
- self.first_no_bin_channel = j
552
- found = True
553
- break
554
-
555
- # If found high values divide masks
556
- if self.first_no_bin_channel != -1:
557
- if self.first_no_bin_channel != 0:
558
- if np.max(mask[...,:self.first_no_bin_channel]) > 30: self.div_Y_on_load_bin_channels = True
559
- if np.max(mask[...,self.first_no_bin_channel:]) > 30: self.div_Y_on_load_no_bin_channels = True
548
+ # Store which channels are binary or not (e.g. distance transform channel is not binary)
549
+ if not analized:
550
+ if n_classes > 2 and instance_problem:
551
+ self.channels_to_analize = mask.shape[-1]-1
552
+ self.channel_info[self.channels_to_analize] = {'type': 'classes'}
553
+ self.channel_info[self.channels_to_analize]['div'] = False
560
554
  else:
561
- if np.max(mask) > 30: self.div_Y_on_load_bin_channels = True
562
- if np.max(mask) > 30: self.div_Y_on_load_no_bin_channels = True
563
- else:
564
- if np.max(mask) > 30: self.div_Y_on_load_bin_channels = True
555
+ self.channels_to_analize = mask.shape[-1]
556
+ analized = True
557
+
558
+ for j in range(self.channels_to_analize):
559
+ if j not in self.channel_info:
560
+ self.channel_info[j] = {'type': 'bin'}
561
+ self.channel_info[j]['div'] = False
562
+
563
+ if instance_problem:
564
+ if len(np.unique(mask[...,j])) > 2:
565
+ self.channel_info[j]['type'] = 'no_bin'
566
+ self.no_bin_channel_found = True
567
+ if np.max(mask[...,j]) > 30:
568
+ self.channel_info[j]['div'] = True
569
+ else: # In semantic seg, maybe the mask are in 255
570
+ if np.max(mask[...,j]) > n_classes:
571
+ self.channel_info[j]['div'] = True
572
+
573
+ if self.channels_to_analize == -1:
574
+ self.channels_to_analize = mask.shape[-1]
565
575
  self.Y_channels = mask.shape[-1]
566
576
  self.Y_dtype = mask.dtype
567
577
  del mask
@@ -777,12 +787,9 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
777
787
  # Choose the data source
778
788
  idx = _idx % self.length
779
789
  if self.in_memory:
780
- img = self.X[idx]
781
- img = np.squeeze(img)
782
-
790
+ img = np.squeeze(self.X[idx].copy())
783
791
  if self.Y_provided:
784
- mask = self.Y[idx]
785
- mask = np.squeeze(mask)
792
+ mask = np.squeeze(self.Y[idx].copy())
786
793
  else:
787
794
  if self.data_paths[idx].endswith('.npy'):
788
795
  img = np.load(os.path.join(self.paths[0], self.data_paths[idx]))
@@ -795,15 +802,17 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
795
802
  img = np.squeeze(img)
796
803
  if self.Y_provided:
797
804
  mask = np.squeeze(mask)
798
-
799
- img = self.norm_X(img)
800
805
 
801
806
  if self.Y_provided:
802
- mask = self.norm_Y(mask)
803
807
  img, mask = self.ensure_shape(img, mask)
804
- return img, mask
805
808
  else:
806
809
  img = self.ensure_shape(img, None)
810
+
811
+ img = self.norm_X(img)
812
+ if self.Y_provided:
813
+ mask = self.norm_Y(mask)
814
+ return img, mask
815
+ else:
807
816
  return img, np.zeros(img.shape, dtype=np.float32)
808
817
 
809
818
  def norm_X(self, img):
@@ -843,19 +852,12 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
843
852
  mask : 3D/4D Numpy array
844
853
  Y element normalized. E.g. ``(y, x, channels)`` in ``2D`` and ``(z, y, x, channels)`` in ``3D``.
845
854
  """
846
- # Y normalization
855
+ # Y normalization
847
856
  if self.X_norm['type'] != "none":
848
- if self.normalizeY == 'as_mask' and self.Y_provided:
849
- if self.first_no_bin_channel != -1:
850
- if self.div_Y_on_load_bin_channels:
851
- mask[...,:self.first_no_bin_channel] = mask[...,:self.first_no_bin_channel]/255
852
- if self.div_Y_on_load_no_bin_channels:
853
- if self.first_no_bin_channel != 0:
854
- mask[...,self.first_no_bin_channel:] = mask[...,self.first_no_bin_channel:]/255
855
- else:
856
- mask = mask/255
857
- else:
858
- if self.div_Y_on_load_bin_channels: mask = mask/255
857
+ if self.normalizeY == 'as_mask' and self.Y_provided:
858
+ for j in range(self.channels_to_analize):
859
+ if self.channel_info[j]['div']:
860
+ mask[...,j] = mask[...,j]/255
859
861
  elif self.normalizeY == 'as_image' and self.Y_provided:
860
862
  if self.X_norm['type'] == 'div':
861
863
  mask, _ = norm_range01(mask)
@@ -965,20 +967,26 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
965
967
  Transformed image mask. E.g. ``(y, x, channels)`` in ``2D`` or ``(y, x, z, channels)`` in ``3D``.
966
968
  """
967
969
  # Split heatmaps from masks
968
- if self.first_no_bin_channel != -1:
969
- if self.first_no_bin_channel != 0:
970
- heat = mask[...,self.first_no_bin_channel:]
971
- mask = mask[...,:self.first_no_bin_channel]
970
+ heat = None
971
+ if self.no_bin_channel_found:
972
+ heat = []
973
+ new_mask = []
974
+ for j in range(mask.shape[-1]):
975
+ if self.channel_info[j]['type'] == "no_bin":
976
+ heat.append(np.expand_dims(mask[...,j],-1))
977
+ else:
978
+ new_mask.append(np.expand_dims(mask[...,j],-1))
979
+
980
+ heat = np.concatenate(heat, axis=-1)
981
+ if len(new_mask) == 0:
982
+ mask = np.zeros(mask.shape) # Fake mask
972
983
  else:
973
- heat = mask
974
- mask = np.zeros(mask.shape) # Fake mask
984
+ mask = np.concatenate(new_mask, axis=-1)
985
+ del new_mask
986
+
975
987
  o_heat_shape = heat.shape
976
- o_mask_shape = mask.shape
977
988
  if self.ndim == 3:
978
989
  heat = heat.reshape(heat.shape[:(self.ndim-1)]+(heat.shape[2]*heat.shape[3],))
979
- heat = HeatmapsOnImage(heat, shape=heat.shape, min_value=0.0, max_value=np.max(heat)+sys.float_info.epsilon)
980
- else:
981
- heat = None
982
990
 
983
991
  # Save shape
984
992
  o_img_shape = image.shape
@@ -994,11 +1002,13 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
994
1002
 
995
1003
  # Apply random rotations
996
1004
  if self.rand_rot and random.uniform(0, 1) < self.da_prob:
997
- image, mask = rotation(image, mask, angles=self.rnd_rot_range, mode=self.affine_mode, mask_type=self.normalizeY)
1005
+ image, mask, heat = rotation(image, mask, heat=heat, angles=self.rnd_rot_range, mode=self.affine_mode,
1006
+ mask_type=self.normalizeY)
998
1007
 
999
1008
  # Apply square rotations
1000
1009
  if self.rotation90 and random.uniform(0, 1) < self.da_prob:
1001
- image, mask = rotation(image, mask, angles=[90, 180, 270], mode=self.affine_mode, mask_type=self.normalizeY)
1010
+ image, mask, heat = rotation(image, mask, heat=heat, angles=[90, 180, 270], mode=self.affine_mode,
1011
+ mask_type=self.normalizeY)
1002
1012
 
1003
1013
  # Reshape 3D volumes to 2D image type with multiple channels to pass through imgaug lib
1004
1014
  if self.ndim == 3:
@@ -1007,6 +1017,9 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
1007
1017
  if e_im is not None: e_im = e_im.reshape(e_im.shape[:2]+(e_im.shape[2]*e_im.shape[3],))
1008
1018
  if e_mask is not None: e_mask = e_mask.reshape(e_mask.shape[:2]+(e_mask.shape[2]*e_mask.shape[3],))
1009
1019
  #if e_heat is not None: e_heat = e_heat.reshape(e_heat.shape[:2]+(e_heat.shape[2]*e_heat.shape[3],))
1020
+ # Convert heatmap into imgaug object
1021
+ if heat is not None:
1022
+ heat = HeatmapsOnImage(heat, shape=heat.shape, min_value=0.0, max_value=np.max(heat)+sys.float_info.epsilon)
1010
1023
 
1011
1024
  # Apply cutout
1012
1025
  if self.cutout and random.uniform(0, 1) < self.da_prob:
@@ -1091,14 +1104,21 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
1091
1104
  mask = mask.reshape(o_mask_shape)
1092
1105
 
1093
1106
  # Merge heatmaps and masks again
1094
- if self.first_no_bin_channel != -1:
1107
+ if self.no_bin_channel_found:
1095
1108
  heat = heat_out.get_arr()
1096
1109
  if self.ndim == 3:
1097
1110
  heat = heat.reshape(o_heat_shape)
1098
- if self.first_no_bin_channel != 0:
1099
- mask = np.concatenate((mask,heat),axis=-1)
1100
- else:
1101
- mask = heat
1111
+
1112
+ new_mask = []
1113
+ hi, mi = 0, 0
1114
+ for j in range(len(self.channel_info)):
1115
+ if self.channel_info[j]['type'] == "no_bin":
1116
+ new_mask.append(np.expand_dims(heat[...,hi],-1))
1117
+ hi += 1
1118
+ else:
1119
+ new_mask.append(np.expand_dims(mask[...,mi],-1))
1120
+ mi += 1
1121
+ mask = np.concatenate(new_mask, axis=-1)
1102
1122
 
1103
1123
  return image, mask
1104
1124
 
@@ -376,8 +376,7 @@ class SingleBaseDataGenerator(Dataset, metaclass=ABCMeta):
376
376
  """
377
377
  # Choose the data source
378
378
  if self.in_memory:
379
- img = self.X[idx]
380
- img = np.squeeze(img)
379
+ img = np.squeeze(self.X[idx].copy())
381
380
  img_class = self.Y[idx] if self.ptype == "classification" else 0
382
381
  else:
383
382
  sample_id = self.all_samples[idx]
@@ -33,6 +33,7 @@ from biapy.utils.util import pad_and_reflect, save_tif
33
33
  from biapy.data.pre_processing import normalize
34
34
  from biapy.data.data_3D_manipulation import crop_3D_data_with_overlap
35
35
  from biapy.data.pre_processing import reduce_dtype
36
+ from biapy.utils.misc import to_numpy_format, to_pytorch_format
36
37
 
37
38
  def boundary_refinement_watershed(X, Y_pred, erode=True, save_marks_dir=None):
38
39
  """Apply watershed to the given predictions with the goal of refine the boundaries of the artifacts.
@@ -489,7 +490,7 @@ def calculate_z_filtering(data, mf_size=5):
489
490
 
490
491
  return out_data
491
492
 
492
- def ensemble8_2d_predictions(o_img, pred_func, batch_size_value=1):
493
+ def ensemble8_2d_predictions(o_img, pred_func, axis_order_back, axis_order, device, batch_size_value=1):
493
494
  """
494
495
  Outputs the mean prediction of a given image generating its 8 possible rotations and flips.
495
496
 
@@ -501,6 +502,15 @@ def ensemble8_2d_predictions(o_img, pred_func, batch_size_value=1):
501
502
  pred_func : function
502
503
  Function to make predictions.
503
504
 
505
+ axis_order_back : tuple
506
+ Axis order to convert from tensor to numpy. E.g. ``(0,3,1,2)``.
507
+
508
+ axis_order : tuple
509
+ Axis order to convert from numpy to tensor. E.g. ``(0,3,1,2)``.
510
+
511
+ device : Torch device
512
+ Device used.
513
+
504
514
  batch_size_value : int, optional
505
515
  Batch size value.
506
516
 
@@ -567,9 +577,12 @@ def ensemble8_2d_predictions(o_img, pred_func, batch_size_value=1):
567
577
  r_aux = pred_func(total_img[i*batch_size_value:top])
568
578
 
569
579
  # Take just the last output of the network in case it returns more than one output
580
+ channel_split = None
570
581
  if isinstance(r_aux, list):
571
- r_aux = np.array(r_aux[-1])
572
-
582
+ channel_split = r_aux[0].shape[1]
583
+ r_aux = np.concatenate([to_numpy_format(r_aux[0], axis_order_back),to_numpy_format(r_aux[1], axis_order_back)],axis=-1)
584
+ else:
585
+ r_aux = to_numpy_format(r_aux, axis_order_back)
573
586
  _decoded_aug_img.append(r_aux)
574
587
  _decoded_aug_img = np.concatenate(_decoded_aug_img)
575
588
 
@@ -611,10 +624,16 @@ def ensemble8_2d_predictions(o_img, pred_func, batch_size_value=1):
611
624
  else:
612
625
  out[i] = out_img[i,:,abs(pad_to_square):]
613
626
 
614
- return np.mean(out, axis=0)
627
+ out = np.expand_dims(np.mean(out, axis=0),0)
628
+ out = to_pytorch_format(out, axis_order, device)
629
+
630
+ if channel_split is not None:
631
+ return [out[:,:channel_split],out[:,channel_split:]]
632
+ else:
633
+ return out
615
634
 
616
635
 
617
- def ensemble16_3d_predictions(vol, pred_func, batch_size_value=1):
636
+ def ensemble16_3d_predictions(vol, pred_func, axis_order_back, axis_order, device, batch_size_value=1):
618
637
  """
619
638
  Outputs the mean prediction of a given image generating its 16 possible rotations and flips.
620
639
 
@@ -625,6 +644,15 @@ def ensemble16_3d_predictions(vol, pred_func, batch_size_value=1):
625
644
 
626
645
  pred_func : function
627
646
  Function to make predictions.
647
+
648
+ axis_order_back : tuple
649
+ Axis order to convert from tensor to numpy. E.g. ``(0,3,1,2,4)``.
650
+
651
+ axis_order : tuple
652
+ Axis order to convert from numpy to tensor. E.g. ``(0,3,1,2,4)``.
653
+
654
+ device : Torch device
655
+ Device used.
628
656
 
629
657
  batch_size_value : int, optional
630
658
  Batch size value.
@@ -703,8 +731,12 @@ def ensemble16_3d_predictions(vol, pred_func, batch_size_value=1):
703
731
  r_aux = pred_func(total_vol[i*batch_size_value:top])
704
732
 
705
733
  # Take just the last output of the network in case it returns more than one output
734
+ channel_split = None
706
735
  if isinstance(r_aux, list):
707
- r_aux = np.array(r_aux[-1])
736
+ channel_split = r_aux[0].shape[1]
737
+ r_aux = np.concatenate([to_numpy_format(r_aux[0], axis_order_back),to_numpy_format(r_aux[1], axis_order_back)],axis=-1)
738
+ else:
739
+ r_aux = to_numpy_format(r_aux, axis_order_back)
708
740
 
709
741
  if r_aux.ndim == 4:
710
742
  r_aux = np.expand_dims(r_aux, 0)
@@ -759,7 +791,13 @@ def ensemble16_3d_predictions(vol, pred_func, batch_size_value=1):
759
791
  else:
760
792
  out[i] = out_vols[i,:,abs(pad_to_square):,:,:]
761
793
 
762
- return np.mean(out, axis=0)
794
+ out = np.expand_dims(np.mean(out, axis=0),0)
795
+ out = to_pytorch_format(out, axis_order, device)
796
+
797
+ if channel_split is not None:
798
+ return [out[:,:channel_split],out[:,channel_split:]]
799
+ else:
800
+ return out
763
801
 
764
802
 
765
803
  def create_th_plot(ths, y_list, th_name="TH_BINARY_MASK", chart_dir=None, per_sample=True, ideal_value=None):
@@ -48,11 +48,32 @@ def create_instance_channels(cfg, data_type='train'):
48
48
  print("Creating Y_{} channels . . .".format(data_type))
49
49
  if isinstance(Y, list):
50
50
  for i in tqdm(range(len(Y))):
51
- Y[i] = labels_into_channels(Y[i], mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
52
- fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
51
+ if cfg.MODEL.N_CLASSES > 2:
52
+ if Y[i].shape[-1] != 2:
53
+ raise ValueError("In instance segmentation, when 'MODEL.N_CLASSES' are more than 2 labels need to have two channels, "
54
+ "e.g. (256,256,2), containing the instance segmentation map (first channel) and classification map (second channel).")
55
+ else:
56
+ class_channel = np.expand_dims(Y[i,...,1].copy(),-1)
57
+ Y[i] = labels_into_channels(Y[i], mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
58
+ fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
59
+ Y[i] = np.concatenate([Y[i],class_channel],axis=-1)
60
+ else:
61
+ Y[i] = labels_into_channels(Y[i], mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
62
+ fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
53
63
  else:
54
- Y = labels_into_channels(Y, mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
55
- fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
64
+ if cfg.MODEL.N_CLASSES > 2:
65
+ if Y.shape[-1] != 2:
66
+ raise ValueError("In instance segmentation, when 'MODEL.N_CLASSES' are more than 2 labels need to have two channels, "
67
+ "e.g. (256,256,2), containing the instance segmentation map (first channel) and classification map (second channel).")
68
+ else:
69
+ class_channel = np.expand_dims(Y[...,1].copy(),-1)
70
+ Y = labels_into_channels(Y, mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
71
+ fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
72
+ Y = np.concatenate([Y, class_channel], axis=-1)
73
+ else:
74
+ Y = labels_into_channels(Y, mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
75
+ fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
76
+
56
77
  save_tif(Y, data_dir=getattr(cfg.DATA, tag).INSTANCE_CHANNELS_MASK_DIR, filenames=filenames, verbose=cfg.TEST.VERBOSE)
57
78
  X, _, _, filenames = f_name(getattr(cfg.DATA, tag).PATH, return_filenames=True)
58
79
  print("Creating X_{} channels . . .".format(data_type))