biapy 3.4.3__tar.gz → 3.4.4__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.
- {biapy-3.4.3 → biapy-3.4.4}/PKG-INFO +1 -1
- {biapy-3.4.3 → biapy-3.4.4}/biapy/config/config.py +28 -5
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/data_3D_manipulation.py +69 -7
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/__init__.py +6 -4
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/pair_base_data_generator.py +3 -32
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/pre_processing.py +122 -15
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/base_workflow.py +248 -220
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/check_configuration.py +38 -19
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/instance_seg.py +98 -33
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/run_checks.py +545 -182
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/tif_to_h5.py +1 -1
- biapy-3.4.4/biapy/utils/scripts/tif_to_zarr.py +43 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/util.py +33 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy.egg-info/PKG-INFO +1 -1
- {biapy-3.4.3 → biapy-3.4.4}/biapy.egg-info/SOURCES.txt +2 -1
- {biapy-3.4.3 → biapy-3.4.4}/pyproject.toml +1 -1
- {biapy-3.4.3 → biapy-3.4.4}/LICENSE.md +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/README.md +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/__init__.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/_biapy.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/config/__init__.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/__init__.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/data_2D_manipulation.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/augmentors.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/pair_data_2D_generator.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/pair_data_3D_generator.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/single_base_data_generator.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/single_data_2D_generator.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/single_data_3D_generator.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/test_pair_data_generators.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/generators/test_single_data_generator.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/post_processing/__init__.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/post_processing/post_processing.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/data/post_processing/smooth_tiled_predictions.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/__init__.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/classification.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/denoising.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/detection.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/image_to_image.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/metrics.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/schedulers/warmup_cosine_decay.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/self_supervised.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/semantic_seg.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/super_resolution.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/engine/train_engine.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/__init__.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/attention_unet.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/blocks.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/dfcan.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/edsr.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/efficientnet.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/mae.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/multiresunet.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/rcan.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/resunet++.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/resunet.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/seunet.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/simple_cnn.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/tr_layers.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/unet.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/unetr.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/vit.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/models/wdsr.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/callbacks.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/matching.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/misc.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/calculate_detection_metrics.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/calculate_metrics_3D.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/create_probability_csv.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/crop_2D_dataset.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/crop_3D_dataset.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/crop_and_discard_3D_dataset.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/detection_plots.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/detection_probs_to_points.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/fill_holes_in_seg_masks.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/filter_close_points.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/from_class_csv_to_folders.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/h5_to_tif.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/h5_to_zarr.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/lightmycell_data_preparation.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/merge_dataset_channels.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy/utils/scripts/order_axes.py +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy.egg-info/dependency_links.txt +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy.egg-info/entry_points.txt +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy.egg-info/requires.txt +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/biapy.egg-info/top_level.txt +0 -0
- {biapy-3.4.3 → biapy-3.4.4}/setup.cfg +0 -0
|
@@ -216,6 +216,13 @@ class Config:
|
|
|
216
216
|
_C.DATA.TRAIN.IN_MEMORY = True
|
|
217
217
|
_C.DATA.TRAIN.PATH = os.path.join("user_data", 'train', 'x')
|
|
218
218
|
_C.DATA.TRAIN.GT_PATH = os.path.join("user_data", 'train', 'y')
|
|
219
|
+
# Whether if your input Zarr contains the raw images and labels together or not. Use 'DATA.TRAIN.INPUT_ZARR_MULTIPLE_DATA_RAW_PATH'
|
|
220
|
+
# and 'DATA.TRAIN.INPUT_ZARR_MULTIPLE_DATA_GT_PATH' to determine the tag to find within the Zarr
|
|
221
|
+
_C.DATA.TRAIN.INPUT_ZARR_MULTIPLE_DATA = False
|
|
222
|
+
# Paths to the raw and gt within the Zarr file. Only used when 'DATA.TRAIN.INPUT_ZARR_MULTIPLE_DATA' is True.
|
|
223
|
+
# E.g. 'volumes.raw' for raw and 'volumes.labels.neuron_ids' for GT path.
|
|
224
|
+
_C.DATA.TRAIN.INPUT_ZARR_MULTIPLE_DATA_RAW_PATH = ''
|
|
225
|
+
_C.DATA.TRAIN.INPUT_ZARR_MULTIPLE_DATA_GT_PATH = ''
|
|
219
226
|
# File to load/save data prepared with the appropiate channels in a instance segmentation problem.
|
|
220
227
|
# E.g. _C.PROBLEM.TYPE ='INSTANCE_SEG' and _C.PROBLEM.INSTANCE_SEG.DATA_CHANNELS != 'B'
|
|
221
228
|
_C.DATA.TRAIN.INSTANCE_CHANNELS_DIR = os.path.join("user_data", 'train', 'x_'+_C.PROBLEM.INSTANCE_SEG.DATA_CHANNELS)
|
|
@@ -240,9 +247,9 @@ class Config:
|
|
|
240
247
|
# Minimum foreground percentage that each image loaded need to have to not discard it (only used when TRAIN.IN_MEMORY == True).
|
|
241
248
|
# This option is only valid for SEMANTIC_SEG, INSTANCE_SEG and DETECTION.
|
|
242
249
|
_C.DATA.TRAIN.MINIMUM_FOREGROUND_PER = -1.
|
|
243
|
-
# Order of the axes of the image when using Zarr/H5 images
|
|
250
|
+
# Order of the axes of the image when using Zarr/H5 images in train data.
|
|
244
251
|
_C.DATA.TRAIN.INPUT_IMG_AXES_ORDER = 'TZCYX'
|
|
245
|
-
# Order of the axes of the mask when using Zarr/H5 images
|
|
252
|
+
# Order of the axes of the mask when using Zarr/H5 images in train data.
|
|
246
253
|
_C.DATA.TRAIN.INPUT_MASK_AXES_ORDER = 'TZCYX'
|
|
247
254
|
|
|
248
255
|
# PREPROCESSING
|
|
@@ -370,6 +377,13 @@ class Config:
|
|
|
370
377
|
_C.DATA.VAL.PATH = os.path.join("user_data", 'val', 'x')
|
|
371
378
|
# Path to the validation data mask. Used when _C.DATA.VAL.FROM_TRAIN = False
|
|
372
379
|
_C.DATA.VAL.GT_PATH = os.path.join("user_data", 'val', 'y')
|
|
380
|
+
# Whether if your input Zarr contains the raw images and labels together or not. Use 'DATA.VAL.INPUT_ZARR_MULTIPLE_DATA_RAW_PATH'
|
|
381
|
+
# and 'DATA.VAL.INPUT_ZARR_MULTIPLE_DATA_GT_PATH' to determine the tag to find within the Zarr
|
|
382
|
+
_C.DATA.VAL.INPUT_ZARR_MULTIPLE_DATA = False
|
|
383
|
+
# Paths to the raw and gt within the Zarr file. Only used when 'DATA.VAL.INPUT_ZARR_MULTIPLE_DATA' is True.
|
|
384
|
+
# E.g. 'volumes.raw' for raw and 'volumes.labels.neuron_ids' for GT path.
|
|
385
|
+
_C.DATA.VAL.INPUT_ZARR_MULTIPLE_DATA_RAW_PATH = ''
|
|
386
|
+
_C.DATA.VAL.INPUT_ZARR_MULTIPLE_DATA_GT_PATH = ''
|
|
373
387
|
# File to load/save data prepared with the appropiate channels in a instance segmentation problem.
|
|
374
388
|
# E.g. _C.PROBLEM.TYPE ='INSTANCE_SEG' and _C.PROBLEM.INSTANCE_SEG.DATA_CHANNELS != 'B'
|
|
375
389
|
_C.DATA.VAL.INSTANCE_CHANNELS_DIR = os.path.join("user_data", 'val', 'x_'+_C.PROBLEM.INSTANCE_SEG.DATA_CHANNELS)
|
|
@@ -388,10 +402,9 @@ class Config:
|
|
|
388
402
|
_C.DATA.VAL.PADDING = (0,0)
|
|
389
403
|
# Not used yet.
|
|
390
404
|
_C.DATA.VAL.RESOLUTION = (-1,)
|
|
391
|
-
# Order of the axes of the image when using Zarr/H5 images
|
|
405
|
+
# Order of the axes of the image when using Zarr/H5 images in validation data.
|
|
392
406
|
_C.DATA.VAL.INPUT_IMG_AXES_ORDER = 'TZCYX'
|
|
393
|
-
# Order of the axes of the mask when using Zarr/H5 images
|
|
394
|
-
# detection the mask
|
|
407
|
+
# Order of the axes of the mask when using Zarr/H5 images in validation data.
|
|
395
408
|
_C.DATA.VAL.INPUT_MASK_AXES_ORDER = 'TZCYX'
|
|
396
409
|
|
|
397
410
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -820,6 +833,16 @@ class Config:
|
|
|
820
833
|
_C.TEST.BY_CHUNKS.FLUSH_EACH = 100
|
|
821
834
|
# Input Numpy/Zarr/H5 image's axes order. Options: ['TZCYX', 'TZYXC', 'ZCYX', 'ZYXC']
|
|
822
835
|
_C.TEST.BY_CHUNKS.INPUT_IMG_AXES_ORDER = 'TZCYX'
|
|
836
|
+
# Input Numpy/Zarr/H5 image's axes order. Options: ['TZCYX', 'TZYXC', 'ZCYX', 'ZYXC']
|
|
837
|
+
_C.TEST.BY_CHUNKS.INPUT_MASK_AXES_ORDER = 'TZCYX'
|
|
838
|
+
# Whether if your input Zarr contains the raw images and labels together or not. Use 'TEST.BY_CHUNKS.INPUT_ZARR_MULTIPLE_DATA_RAW_PATH'
|
|
839
|
+
# and 'TEST.BY_CHUNKS.INPUT_ZARR_MULTIPLE_DATA_GT_PATH' to determine the tag to find within the Zarr
|
|
840
|
+
_C.TEST.BY_CHUNKS.INPUT_ZARR_MULTIPLE_DATA = False
|
|
841
|
+
# Paths to the raw and gt within the Zarr file. Only used when 'TEST.BY_CHUNKS.INPUT_ZARR_MULTIPLE_DATA' is True.
|
|
842
|
+
# E.g. 'volumes.raw' for raw and 'volumes.labels.neuron_ids' for GT path.
|
|
843
|
+
_C.TEST.BY_CHUNKS.INPUT_ZARR_MULTIPLE_DATA_RAW_PATH = ''
|
|
844
|
+
_C.TEST.BY_CHUNKS.INPUT_ZARR_MULTIPLE_DATA_GT_PATH = ''
|
|
845
|
+
|
|
823
846
|
# Whether if after reconstructing the prediction the pipeline will continue each workflow specific steps. For this process
|
|
824
847
|
# the prediction image needs to be loaded into memory so be sure that it can fit in you memory. E.g. in instance
|
|
825
848
|
# segmentation the instances will be created from the prediction.
|
|
@@ -6,7 +6,7 @@ from skimage.io import imread
|
|
|
6
6
|
from tqdm import tqdm
|
|
7
7
|
from sklearn.model_selection import train_test_split, StratifiedKFold
|
|
8
8
|
|
|
9
|
-
from biapy.utils.util import load_3d_images_from_dir, order_dimensions, read_chunked_data
|
|
9
|
+
from biapy.utils.util import load_3d_images_from_dir, order_dimensions, read_chunked_data, read_chunked_nested_data
|
|
10
10
|
from biapy.utils.misc import is_main_process
|
|
11
11
|
|
|
12
12
|
def load_and_prepare_3D_data(train_path, train_mask_path, cross_val=False, cross_val_nsplits=5, cross_val_fold=1,
|
|
@@ -381,7 +381,7 @@ def load_and_prepare_3D_data(train_path, train_mask_path, cross_val=False, cross
|
|
|
381
381
|
|
|
382
382
|
def load_and_prepare_3D_efficient_format_data(train_path, train_mask_path, input_img_axes, input_mask_axes=None, cross_val=False,
|
|
383
383
|
cross_val_nsplits=5, cross_val_fold=1, val_split=0.1, seed=0, shuffle_val=True, crop_shape=(80, 80, 80, 1), y_upscaling=(1,1,1),
|
|
384
|
-
ov=(0,0,0), padding=(0,0,0), minimum_foreground_perc=-1):
|
|
384
|
+
ov=(0,0,0), padding=(0,0,0), minimum_foreground_perc=-1, multiple_data_within_zarr=None):
|
|
385
385
|
"""
|
|
386
386
|
Load train and validation images from the given paths to create 3D data.
|
|
387
387
|
|
|
@@ -433,6 +433,9 @@ def load_and_prepare_3D_efficient_format_data(train_path, train_mask_path, input
|
|
|
433
433
|
minimum_foreground_perc : float, optional
|
|
434
434
|
Minimum percetnage of foreground that a sample need to have no not be discarded.
|
|
435
435
|
|
|
436
|
+
multiple_data_within_zarr : dict, optional
|
|
437
|
+
Additional information of where to find the data within the Zarr files.
|
|
438
|
+
|
|
436
439
|
Returns
|
|
437
440
|
-------
|
|
438
441
|
X_train : 5D Numpy array
|
|
@@ -457,7 +460,9 @@ def load_and_prepare_3D_efficient_format_data(train_path, train_mask_path, input
|
|
|
457
460
|
create_val = False
|
|
458
461
|
|
|
459
462
|
print("0) Loading train image information . . .")
|
|
460
|
-
|
|
463
|
+
data_within_zarr_path = multiple_data_within_zarr['raw_path'] if multiple_data_within_zarr is not None else None
|
|
464
|
+
X_train, X_train_total_patches = load_3D_efficient_files(train_path, input_img_axes, crop_shape, ov, padding,
|
|
465
|
+
data_within_zarr_path=data_within_zarr_path)
|
|
461
466
|
|
|
462
467
|
if train_mask_path is not None:
|
|
463
468
|
if input_mask_axes is None:
|
|
@@ -465,8 +470,11 @@ def load_and_prepare_3D_efficient_format_data(train_path, train_mask_path, input
|
|
|
465
470
|
|
|
466
471
|
print("0) Loading train GT information . . .")
|
|
467
472
|
scrop = (crop_shape[0]*y_upscaling[0], crop_shape[1]*y_upscaling[1], crop_shape[2]*y_upscaling[2], crop_shape[3])
|
|
473
|
+
data_within_zarr_path = None
|
|
474
|
+
if multiple_data_within_zarr is not None and multiple_data_within_zarr['use_gt_path']:
|
|
475
|
+
data_within_zarr_path = multiple_data_within_zarr['gt_path']
|
|
468
476
|
Y_train, Y_train_total_patches = load_3D_efficient_files(train_mask_path, input_mask_axes, scrop, ov, padding,
|
|
469
|
-
check_channel=False)
|
|
477
|
+
check_channel=False, data_within_zarr_path=data_within_zarr_path)
|
|
470
478
|
|
|
471
479
|
for i in range(len(Y_train_total_patches)):
|
|
472
480
|
if Y_train_total_patches[i] != X_train_total_patches[i]:
|
|
@@ -629,7 +637,8 @@ def load_and_prepare_3D_efficient_format_data(train_path, train_mask_path, input
|
|
|
629
637
|
print("*** Loaded train GT shape is: {}".format(yshape))
|
|
630
638
|
return X_train, Y_train
|
|
631
639
|
|
|
632
|
-
def load_3D_efficient_files(data_path, input_axes, crop_shape, overlap, padding, check_channel=True
|
|
640
|
+
def load_3D_efficient_files(data_path, input_axes, crop_shape, overlap, padding, check_channel=True,
|
|
641
|
+
data_within_zarr_path=None):
|
|
633
642
|
"""
|
|
634
643
|
Load information of all patches that can be extracted from all the Zarr/H5 samples in ``data_path``.
|
|
635
644
|
|
|
@@ -654,6 +663,9 @@ def load_3D_efficient_files(data_path, input_axes, crop_shape, overlap, padding,
|
|
|
654
663
|
check_channel : bool, optional
|
|
655
664
|
Whether to check if the crop_shape channel matches with the loaded images' one.
|
|
656
665
|
|
|
666
|
+
data_within_zarr_path : str, optional
|
|
667
|
+
Path to find the data within the Zarr file. E.g. 'volumes.labels.neuron_ids'.
|
|
668
|
+
|
|
657
669
|
Returns
|
|
658
670
|
-------
|
|
659
671
|
data_info : dict
|
|
@@ -669,8 +681,11 @@ def load_3D_efficient_files(data_path, input_axes, crop_shape, overlap, padding,
|
|
|
669
681
|
|
|
670
682
|
for i, filename in enumerate(data_path):
|
|
671
683
|
print(f"Reading Zarr/H5 file: {filename}")
|
|
672
|
-
|
|
673
|
-
|
|
684
|
+
if data_within_zarr_path:
|
|
685
|
+
file, data = read_chunked_nested_data(filename, data_within_zarr_path)
|
|
686
|
+
else:
|
|
687
|
+
file, data = read_chunked_data(filename)
|
|
688
|
+
|
|
674
689
|
# Modify crop_shape with the channel
|
|
675
690
|
c_index = -1
|
|
676
691
|
try:
|
|
@@ -714,6 +729,53 @@ def load_3D_efficient_files(data_path, input_axes, crop_shape, overlap, padding,
|
|
|
714
729
|
|
|
715
730
|
return data_info, data_total_patches
|
|
716
731
|
|
|
732
|
+
def load_img_part_from_efficient_file(filepath, patch_coords, data_axis_order="ZYXC", data_path=None):
|
|
733
|
+
"""
|
|
734
|
+
Loads from ``filepath`` the patch determined by ``patch_coords``.
|
|
735
|
+
|
|
736
|
+
Parameters
|
|
737
|
+
----------
|
|
738
|
+
filepath : str
|
|
739
|
+
Path to the Zarr/H5 file to read the patch from.
|
|
740
|
+
|
|
741
|
+
patch_coords : Tuple of tuples of ints
|
|
742
|
+
Coordinates of patch to extract.
|
|
743
|
+
|
|
744
|
+
data_axis_order : str
|
|
745
|
+
Order of axes of ``data``. E.g. 'TZCYX', 'TZYXC', 'ZCYX', 'ZYXC'.
|
|
746
|
+
|
|
747
|
+
data_path : str, optional
|
|
748
|
+
Path to find the data within the Zarr file. E.g. 'volumes.labels.neuron_ids'.
|
|
749
|
+
|
|
750
|
+
Returns
|
|
751
|
+
-------
|
|
752
|
+
img : Numpy array
|
|
753
|
+
Extracted patch. E.g. ``(z, y, x, channels)``.
|
|
754
|
+
"""
|
|
755
|
+
if data_path is not None:
|
|
756
|
+
imgfile, img = read_chunked_nested_data(filepath, data_path)
|
|
757
|
+
else:
|
|
758
|
+
imgfile, img = read_chunked_data(filepath)
|
|
759
|
+
|
|
760
|
+
# Prepare slices to extract the patch
|
|
761
|
+
slices = []
|
|
762
|
+
for j in range(len(patch_coords)):
|
|
763
|
+
if isinstance(patch_coords[j], int):
|
|
764
|
+
# +1 to prevent 0 length axes that can not be removed with np.squeeze later
|
|
765
|
+
slices.append(slice(0,patch_coords[j]+1))
|
|
766
|
+
else:
|
|
767
|
+
slices.append(slice(patch_coords[j][0],patch_coords[j][1]))
|
|
768
|
+
|
|
769
|
+
slices = tuple(slices)
|
|
770
|
+
data_ordered_slices = tuple(order_dimensions(slices, input_order="ZYXC", output_order=data_axis_order,
|
|
771
|
+
default_value=0))
|
|
772
|
+
img = np.squeeze(np.array(img[data_ordered_slices]))
|
|
773
|
+
|
|
774
|
+
if isinstance(imgfile, h5py.File):
|
|
775
|
+
imgfile.close()
|
|
776
|
+
|
|
777
|
+
return img
|
|
778
|
+
|
|
717
779
|
def crop_3D_data_with_overlap(data, vol_shape, data_mask=None, overlap=(0,0,0), padding=(0,0,0), verbose=True,
|
|
718
780
|
median_padding=False):
|
|
719
781
|
"""Crop 3D data into smaller volumes with a defined overlap. The opposite function is :func:`~merge_3D_data_with_overlap`.
|
|
@@ -121,8 +121,9 @@ def create_train_val_augmentors(cfg, X_train, Y_train, X_val, Y_val, world_size,
|
|
|
121
121
|
if cfg.DATA.TRAIN.IN_MEMORY:
|
|
122
122
|
data_mode = "in_memory"
|
|
123
123
|
else:
|
|
124
|
-
if cfg.PROBLEM.NDIM == '3D' and X_train is not None and isinstance(X_train, list)
|
|
125
|
-
'filepath' in X_train[0] and ('.zarr' in X_train[0]['filepath'] or
|
|
124
|
+
if cfg.PROBLEM.NDIM == '3D' and X_train is not None and (isinstance(X_train, list) or isinstance(X_train, dict)) and \
|
|
125
|
+
isinstance(X_train[0], dict) and 'filepath' in X_train[0] and ('.zarr' in X_train[0]['filepath'] or \
|
|
126
|
+
'.h5' in X_train[0]['filepath']):
|
|
126
127
|
data_mode = "chunked_data"
|
|
127
128
|
else:
|
|
128
129
|
data_mode = "not_in_memory"
|
|
@@ -226,8 +227,9 @@ def create_train_val_augmentors(cfg, X_train, Y_train, X_val, Y_val, world_size,
|
|
|
226
227
|
if cfg.DATA.VAL.IN_MEMORY:
|
|
227
228
|
val_data_mode = "in_memory"
|
|
228
229
|
else:
|
|
229
|
-
if cfg.PROBLEM.NDIM == '3D' and X_val is not None and isinstance(X_val, list)
|
|
230
|
-
'filepath' in X_val[0] and ('.zarr' in X_val[0]['filepath'] or
|
|
230
|
+
if cfg.PROBLEM.NDIM == '3D' and X_val is not None and (isinstance(X_val, list) or isinstance(X_val, dict)) and \
|
|
231
|
+
isinstance(X_val[0], dict) and 'filepath' in X_val[0] and ('.zarr' in X_val[0]['filepath'] or \
|
|
232
|
+
'.h5' in X_val[0]['filepath']):
|
|
231
233
|
val_data_mode = "chunked_data"
|
|
232
234
|
else:
|
|
233
235
|
val_data_mode = "not_in_memory"
|
|
@@ -18,6 +18,7 @@ from biapy.utils.util import img_to_onehot_encoding, pad_and_reflect, read_chunk
|
|
|
18
18
|
from biapy.data.generators.augmentors import *
|
|
19
19
|
from biapy.data.pre_processing import normalize, norm_range01, percentile_clip
|
|
20
20
|
from biapy.utils.misc import is_main_process
|
|
21
|
+
from biapy.data.data_3D_manipulation import load_img_part_from_efficient_file
|
|
21
22
|
|
|
22
23
|
class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
|
|
23
24
|
"""
|
|
@@ -832,39 +833,9 @@ class PairBaseDataGenerator(Dataset, metaclass=ABCMeta):
|
|
|
832
833
|
if self.Y_provided:
|
|
833
834
|
mask = np.squeeze(mask)
|
|
834
835
|
else: # self.data_mode == "chunked_data"
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
# Prepare slices to extract the patch
|
|
838
|
-
slices = []
|
|
839
|
-
for j in range(len(self.X[idx]['patch_coords'])):
|
|
840
|
-
if isinstance(self.X[idx]['patch_coords'][j], int):
|
|
841
|
-
# +1 to prevent 0 length axes that can not be removed with np.squeeze later
|
|
842
|
-
slices.append(slice(0,self.X[idx]['patch_coords'][j]+1))
|
|
843
|
-
else:
|
|
844
|
-
slices.append(slice(self.X[idx]['patch_coords'][j][0],self.X[idx]['patch_coords'][j][1]))
|
|
845
|
-
|
|
846
|
-
img = np.squeeze(np.array(img[tuple(slices)]))
|
|
847
|
-
|
|
848
|
-
if isinstance(imgfile, h5py.File):
|
|
849
|
-
imgfile.close()
|
|
850
|
-
|
|
836
|
+
img = load_img_part_from_efficient_file(self.X[idx]['filepath'], self.X[idx]['patch_coords'])
|
|
851
837
|
if self.Y_provided:
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
# Prepare slices to extract the patch
|
|
855
|
-
slices = []
|
|
856
|
-
for j in range(len(self.Y[idx]['patch_coords'])):
|
|
857
|
-
if isinstance(self.Y[idx]['patch_coords'][j], int):
|
|
858
|
-
# +1 to prevent 0 length axes that can not be removed with np.squeeze later
|
|
859
|
-
slices.append(slice(0,self.Y[idx]['patch_coords'][j]+1))
|
|
860
|
-
else:
|
|
861
|
-
slices.append(slice(self.Y[idx]['patch_coords'][j][0],self.Y[idx]['patch_coords'][j][1]))
|
|
862
|
-
|
|
863
|
-
mask = np.squeeze(np.array(mask[tuple(slices)]))
|
|
864
|
-
|
|
865
|
-
if isinstance(maskfile, h5py.File):
|
|
866
|
-
maskfile.close()
|
|
867
|
-
|
|
838
|
+
mask = load_img_part_from_efficient_file(self.Y[idx]['filepath'], self.Y[idx]['patch_coords'])
|
|
868
839
|
if self.Y_provided:
|
|
869
840
|
img, mask = self.ensure_shape(img, mask)
|
|
870
841
|
else:
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import torch
|
|
3
3
|
import scipy
|
|
4
4
|
import h5py
|
|
5
|
+
import zarr
|
|
5
6
|
import numpy as np
|
|
6
7
|
from tqdm import tqdm
|
|
7
8
|
import pandas as pd
|
|
@@ -17,8 +18,10 @@ from skimage.exposure import equalize_adapthist
|
|
|
17
18
|
from skimage.color import rgb2gray
|
|
18
19
|
from skimage.filters import gaussian, median
|
|
19
20
|
|
|
20
|
-
from biapy.utils.util import load_data_from_dir, load_3d_images_from_dir, save_tif, write_chunked_data, read_chunked_data
|
|
21
|
+
from biapy.utils.util import (load_data_from_dir, load_3d_images_from_dir, save_tif, write_chunked_data, read_chunked_data,
|
|
22
|
+
order_dimensions)
|
|
21
23
|
from biapy.utils.misc import is_main_process
|
|
24
|
+
from biapy.data.data_3D_manipulation import load_3D_efficient_files, load_img_part_from_efficient_file
|
|
22
25
|
|
|
23
26
|
#########################
|
|
24
27
|
# INSTANCE SEGMENTATION #
|
|
@@ -42,10 +45,41 @@ def create_instance_channels(cfg, data_type='train'):
|
|
|
42
45
|
"""
|
|
43
46
|
|
|
44
47
|
assert data_type in ['train', 'val']
|
|
45
|
-
|
|
46
|
-
f_name = load_data_from_dir if cfg.PROBLEM.NDIM == '2D' else load_3d_images_from_dir
|
|
47
48
|
tag = "TRAIN" if data_type == "train" else "VAL"
|
|
48
|
-
|
|
49
|
+
|
|
50
|
+
# Checking if the user inputted Zarr/H5 files
|
|
51
|
+
if getattr(cfg.DATA, tag).INPUT_ZARR_MULTIPLE_DATA:
|
|
52
|
+
zarr_files = sorted(next(os.walk(getattr(cfg.DATA, tag).PATH))[1])
|
|
53
|
+
h5_files = sorted(next(os.walk(getattr(cfg.DATA, tag).PATH))[2])
|
|
54
|
+
else:
|
|
55
|
+
zarr_files = sorted(next(os.walk(getattr(cfg.DATA, tag).GT_PATH))[1])
|
|
56
|
+
h5_files = sorted(next(os.walk(getattr(cfg.DATA, tag).GT_PATH))[2])
|
|
57
|
+
|
|
58
|
+
# Find patches info so we can iterate over them to create the instance mask
|
|
59
|
+
working_with_zarr_h5_files = False
|
|
60
|
+
if cfg.PROBLEM.NDIM == '3D' and (len(zarr_files) > 0 and '.zarr' in zarr_files[0]) or \
|
|
61
|
+
(len(h5_files) > 0 and '.h5' in h5_files[0]):
|
|
62
|
+
working_with_zarr_h5_files = True
|
|
63
|
+
# Check if the raw images and labels are within the same file
|
|
64
|
+
mult_dat = None
|
|
65
|
+
data_path = getattr(cfg.DATA, tag).GT_PATH
|
|
66
|
+
if getattr(cfg.DATA, tag).INPUT_ZARR_MULTIPLE_DATA:
|
|
67
|
+
data_path = getattr(cfg.DATA, tag).PATH
|
|
68
|
+
|
|
69
|
+
if len(zarr_files) > 0 and '.zarr' in zarr_files[0]:
|
|
70
|
+
print("Working with Zarr files . . .")
|
|
71
|
+
img_files = [os.path.join(data_path, x) for x in zarr_files]
|
|
72
|
+
elif len(h5_files) > 0 and '.h5' in h5_files[0]:
|
|
73
|
+
print("Working with H5 files . . .")
|
|
74
|
+
img_files = [os.path.join(data_path, x) for x in h5_files]
|
|
75
|
+
|
|
76
|
+
Y, Y_total_patches = load_3D_efficient_files(img_files, input_axes=getattr(cfg.DATA, tag).INPUT_IMG_AXES_ORDER,
|
|
77
|
+
crop_shape=cfg.DATA.PATCH_SIZE, overlap=getattr(cfg.DATA, tag).OVERLAP, padding=getattr(cfg.DATA, tag).PADDING)
|
|
78
|
+
else:
|
|
79
|
+
f_name = load_data_from_dir if cfg.PROBLEM.NDIM == '2D' else load_3d_images_from_dir
|
|
80
|
+
Y, _, _, filenames = f_name(getattr(cfg.DATA, tag).GT_PATH, check_drange=False, return_filenames=True)
|
|
81
|
+
del zarr_files, h5_files
|
|
82
|
+
|
|
49
83
|
print("Creating Y_{} channels . . .".format(data_type))
|
|
50
84
|
if isinstance(Y, list):
|
|
51
85
|
for i in tqdm(range(len(Y)), disable=not is_main_process()):
|
|
@@ -61,6 +95,78 @@ def create_instance_channels(cfg, data_type='train'):
|
|
|
61
95
|
else:
|
|
62
96
|
Y[i] = labels_into_channels(Y[i], mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
|
|
63
97
|
fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
|
|
98
|
+
# Create the mask patch by patch (Zarr/H5)
|
|
99
|
+
elif working_with_zarr_h5_files and isinstance(Y, dict):
|
|
100
|
+
savepath = data_path+'_'+cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS+'_'+cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE
|
|
101
|
+
if 'D' in cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE:
|
|
102
|
+
dtype_str = "float32"
|
|
103
|
+
raise ValueError("Currently distance creation using Zarr by chunks is not implemented.")
|
|
104
|
+
else:
|
|
105
|
+
dtype_str = "uint8"
|
|
106
|
+
|
|
107
|
+
mask = None
|
|
108
|
+
last_zarr_file = None
|
|
109
|
+
for i in tqdm(range(len(Y.keys())), disable=not is_main_process()):
|
|
110
|
+
# Extract the patch to process
|
|
111
|
+
patch_coords = Y[i]['patch_coords']
|
|
112
|
+
img = load_img_part_from_efficient_file(Y[i]['filepath'], patch_coords,
|
|
113
|
+
data_axis_order=getattr(cfg.DATA, tag).INPUT_IMG_AXES_ORDER,
|
|
114
|
+
data_path=getattr(cfg.DATA, tag).INPUT_ZARR_MULTIPLE_DATA_GT_PATH)
|
|
115
|
+
if img.ndim == 3: img = np.expand_dims(img,-1)
|
|
116
|
+
if img.ndim == 4: img = np.expand_dims(img,0)
|
|
117
|
+
|
|
118
|
+
# Create the instance mask
|
|
119
|
+
if cfg.MODEL.N_CLASSES > 2:
|
|
120
|
+
if img.shape[-1] != 2:
|
|
121
|
+
raise ValueError("In instance segmentation, when 'MODEL.N_CLASSES' are more than 2 labels need to have two channels, "
|
|
122
|
+
"e.g. (256,256,2), containing the instance segmentation map (first channel) and classification map (second channel).")
|
|
123
|
+
else:
|
|
124
|
+
class_channel = np.expand_dims(img[...,1].copy(),-1)
|
|
125
|
+
img = labels_into_channels(img, mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
|
|
126
|
+
fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
|
|
127
|
+
img = np.concatenate([img,class_channel],axis=-1)
|
|
128
|
+
else:
|
|
129
|
+
img = labels_into_channels(img, mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
|
|
130
|
+
fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
|
|
131
|
+
img = img[0]
|
|
132
|
+
|
|
133
|
+
# Create the Zarr file where the mask will be placed
|
|
134
|
+
if mask is None or os.path.basename(Y[i]['filepath']) != last_zarr_file:
|
|
135
|
+
last_zarr_file = os.path.basename(Y[i]['filepath'])
|
|
136
|
+
imgfile, data = read_chunked_data(Y[i]['filepath'])
|
|
137
|
+
fname = os.path.join(savepath, os.path.basename(Y[i]['filepath']))
|
|
138
|
+
fid_mask = zarr.open_group(fname, mode="w")
|
|
139
|
+
|
|
140
|
+
# Determine data shape
|
|
141
|
+
out_data_shape = np.array(data.shape)
|
|
142
|
+
if "C" not in getattr(cfg.DATA, tag).INPUT_IMG_AXES_ORDER:
|
|
143
|
+
out_data_shape = tuple(out_data_shape) + (img.shape[-1],)
|
|
144
|
+
out_data_order = getattr(cfg.DATA, tag).INPUT_IMG_AXES_ORDER + "C"
|
|
145
|
+
channel_pos = -1
|
|
146
|
+
else:
|
|
147
|
+
out_data_shape[getattr(cfg.DATA, tag).INPUT_IMG_AXES_ORDER.index("C")] = 1
|
|
148
|
+
out_data_shape = tuple(out_data_shape)
|
|
149
|
+
out_data_order = getattr(cfg.DATA, tag).INPUT_IMG_AXES_ORDER
|
|
150
|
+
channel_pos = getattr(cfg.DATA, tag).INPUT_IMG_AXES_ORDER.index("C")
|
|
151
|
+
|
|
152
|
+
mask = fid_mask.create_dataset("data", shape=out_data_shape, dtype=dtype_str)
|
|
153
|
+
del data, imgfile, fname
|
|
154
|
+
|
|
155
|
+
# Adjust slices to calculate where to insert the predicted patch. This slice does not have into account the
|
|
156
|
+
# channel so any of them can be inserted
|
|
157
|
+
slices = (slice(patch_coords[0][0],patch_coords[0][1]), slice(patch_coords[1][0],patch_coords[1][1]),
|
|
158
|
+
slice(patch_coords[2][0],patch_coords[2][1]), slice(0,out_data_shape[channel_pos]))
|
|
159
|
+
data_ordered_slices = tuple(order_dimensions(slices, input_order="ZYXC",
|
|
160
|
+
output_order=out_data_order, default_value=0))
|
|
161
|
+
|
|
162
|
+
# Adjust patch slice to transpose it before inserting intop the final data
|
|
163
|
+
current_order = np.array(range(len(img.shape)))
|
|
164
|
+
transpose_order = order_dimensions(current_order, input_order="ZYXC", output_order=out_data_order,
|
|
165
|
+
default_value=np.nan)
|
|
166
|
+
transpose_order = [x for x in transpose_order if not np.isnan(x)]
|
|
167
|
+
|
|
168
|
+
# Place the patch into the Zarr
|
|
169
|
+
mask[data_ordered_slices] = img.transpose(transpose_order)
|
|
64
170
|
else:
|
|
65
171
|
if cfg.MODEL.N_CLASSES > 2:
|
|
66
172
|
if Y.shape[-1] != 2:
|
|
@@ -75,17 +181,18 @@ def create_instance_channels(cfg, data_type='train'):
|
|
|
75
181
|
Y = labels_into_channels(Y, mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CHANNELS, save_dir=getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'),
|
|
76
182
|
fb_mode=cfg.PROBLEM.INSTANCE_SEG.DATA_CONTOUR_MODE)
|
|
77
183
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
184
|
+
if not working_with_zarr_h5_files:
|
|
185
|
+
save_tif(Y, data_dir=getattr(cfg.DATA, tag).INSTANCE_CHANNELS_MASK_DIR, filenames=filenames, verbose=cfg.TEST.VERBOSE)
|
|
186
|
+
X, _, _, filenames = f_name(getattr(cfg.DATA, tag).PATH, return_filenames=True)
|
|
187
|
+
print("Creating X_{} channels . . .".format(data_type))
|
|
188
|
+
save_tif(X, data_dir=getattr(cfg.DATA, tag).INSTANCE_CHANNELS_DIR, filenames=filenames, verbose=cfg.TEST.VERBOSE)
|
|
189
|
+
|
|
190
|
+
# Save original X data with the labels
|
|
191
|
+
for i in range(min(3,len(X))):
|
|
192
|
+
if isinstance(X, list):
|
|
193
|
+
save_tif(X[i], getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'), filenames=['vol'+str(i)+".tif"], verbose=False)
|
|
194
|
+
else:
|
|
195
|
+
save_tif(np.expand_dims(X[i],0), getattr(cfg.PATHS, tag+'_INSTANCE_CHANNELS_CHECK'), filenames=['vol'+str(i)+".tif"], verbose=False)
|
|
89
196
|
|
|
90
197
|
def create_test_instance_channels(cfg):
|
|
91
198
|
"""Create test new data with appropiate channels based on ``PROBLEM.INSTANCE_SEG.DATA_CHANNELS`` for instance segmentation.
|