torch_em.data.datasets.medical.bagls_vf
BAGLS-VF extends the BAGLS glottis segmentation benchmark with pixel-wise annotations of the left vocal fold, right vocal fold and glottal area (3 foreground classes), derived from high-speed videolaryngoscopy recordings. Masks are RGB-coded, with a distinct color per anatomical structure (encoded here as separate label values).
The dataset is located at https://doi.org/10.5281/zenodo.19593658. Please cite it if you use this dataset for your research.
1"""BAGLS-VF extends the BAGLS glottis segmentation benchmark with pixel-wise annotations 2of the left vocal fold, right vocal fold and glottal area (3 foreground classes), derived 3from high-speed videolaryngoscopy recordings. Masks are RGB-coded, with a distinct color 4per anatomical structure (encoded here as separate label values). 5 6The dataset is located at https://doi.org/10.5281/zenodo.19593658. 7Please cite it if you use this dataset for your research. 8""" 9 10import os 11from glob import glob 12from pathlib import Path 13from typing import Union, Tuple, List, Literal 14 15import numpy as np 16import imageio.v3 as imageio 17 18from torch.utils.data import Dataset, DataLoader 19 20import torch_em 21 22from .. import util 23 24 25URLS = { 26 "train": "https://zenodo.org/records/19593658/files/BAGLS-VF_train.zip", 27 "test": "https://zenodo.org/records/19593658/files/BAGLS-VF_test.zip", 28} 29 30CHECKSUMS = { 31 "train": "accc5bc0acf920f344df5efb5b159fd15ad1a0941536542f65080a9f91b94c90", 32 "test": "0876ae6461d5142b08338c4e45b9c96a4aa7642bebab4ce8d4a8508585b0907f", 33} 34 35LABEL_MAP = { 36 (0, 0, 0): 0, # background 37 (0, 0, 255): 1, # vocal fold / glottis structure (blue) 38 (0, 255, 0): 2, # vocal fold / glottis structure (green) 39 (255, 0, 0): 3, # vocal fold / glottis structure (red) 40} 41 42 43def get_bagls_vf_data(path: Union[os.PathLike, str], split: Literal["train", "test"], download: bool = False) -> str: 44 """Download the BAGLS-VF dataset. 45 46 Args: 47 path: Filepath to a folder where the data is downloaded for further processing. 48 split: The choice of data split. 49 download: Whether to download the data if it is not present. 50 51 Returns: 52 Filepath where the data is downloaded. 53 """ 54 data_dir = os.path.join(path, f"BAGLS-VF_{split}") 55 if os.path.exists(data_dir): 56 return data_dir 57 58 os.makedirs(path, exist_ok=True) 59 60 zip_path = os.path.join(path, f"BAGLS-VF_{split}.zip") 61 util.download_source(path=zip_path, url=URLS[split], download=download, checksum=CHECKSUMS[split]) 62 util.unzip(zip_path=zip_path, dst=path) 63 64 return data_dir 65 66 67def get_bagls_vf_paths( 68 path: Union[os.PathLike, str], split: Literal["train", "test"], download: bool = False 69) -> Tuple[List[str], List[str]]: 70 """Get paths to the BAGLS-VF data. 71 72 Args: 73 path: Filepath to a folder where the data is downloaded for further processing. 74 split: The choice of data split. 75 download: Whether to download the data if it is not present. 76 77 Returns: 78 List of filepaths for the image data. 79 List of filepaths for the label data. 80 """ 81 data_dir = get_bagls_vf_data(path=path, split=split, download=download) 82 83 image_paths = sorted(glob(os.path.join(data_dir, f"{split}_images", "*.png"))) 84 mask_dir = os.path.join(data_dir, f"{split}_masks") 85 86 neu_gt_dir = os.path.join(data_dir, "preprocessed_masks") 87 os.makedirs(neu_gt_dir, exist_ok=True) 88 89 gt_paths = [] 90 for image_path in image_paths: 91 fname = Path(image_path).stem 92 mask_path = os.path.join(mask_dir, f"{fname}.png") 93 neu_gt_path = os.path.join(neu_gt_dir, f"{fname}.tif") 94 gt_paths.append(neu_gt_path) 95 96 if os.path.exists(neu_gt_path): 97 continue 98 99 mask = imageio.imread(mask_path)[..., :3] 100 instances = np.zeros(mask.shape[:2], dtype="uint8") 101 for color, label in LABEL_MAP.items(): 102 if label == 0: 103 continue 104 binary_map = (mask == color).all(axis=-1) 105 instances[binary_map] = label 106 107 imageio.imwrite(neu_gt_path, instances, compression="zlib") 108 109 return image_paths, gt_paths 110 111 112def get_bagls_vf_dataset( 113 path: Union[os.PathLike, str], 114 patch_shape: Tuple[int, int], 115 split: Literal["train", "test"], 116 resize_inputs: bool = False, 117 download: bool = False, 118 **kwargs 119) -> Dataset: 120 """Get the BAGLS-VF dataset for vocal fold and glottal area segmentation. 121 122 Args: 123 path: Filepath to a folder where the data is downloaded for further processing. 124 patch_shape: The patch shape to use for training. 125 split: The choice of data split. 126 resize_inputs: Whether to resize the inputs to the patch shape. 127 download: Whether to download the data if it is not present. 128 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 129 130 Returns: 131 The segmentation dataset. 132 """ 133 image_paths, gt_paths = get_bagls_vf_paths(path, split, download) 134 135 if resize_inputs: 136 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True} 137 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 138 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 139 ) 140 141 return torch_em.default_segmentation_dataset( 142 raw_paths=image_paths, 143 raw_key=None, 144 label_paths=gt_paths, 145 label_key=None, 146 patch_shape=patch_shape, 147 is_seg_dataset=False, 148 **kwargs 149 ) 150 151 152def get_bagls_vf_loader( 153 path: Union[os.PathLike, str], 154 patch_shape: Tuple[int, int], 155 batch_size: int, 156 split: Literal["train", "test"], 157 resize_inputs: bool = False, 158 download: bool = False, 159 **kwargs 160) -> DataLoader: 161 """Get the BAGLS-VF dataloader for vocal fold and glottal area segmentation. 162 163 Args: 164 path: Filepath to a folder where the data is downloaded for further processing. 165 patch_shape: The patch shape to use for training. 166 batch_size: The batch size for training. 167 split: The choice of data split. 168 resize_inputs: Whether to resize the inputs to the patch shape. 169 download: Whether to download the data if it is not present. 170 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 171 172 Returns: 173 The DataLoader. 174 """ 175 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 176 dataset = get_bagls_vf_dataset(path, patch_shape, split, resize_inputs, download, **ds_kwargs) 177 return torch_em.get_data_loader(dataset=dataset, batch_size=batch_size, **loader_kwargs)
44def get_bagls_vf_data(path: Union[os.PathLike, str], split: Literal["train", "test"], download: bool = False) -> str: 45 """Download the BAGLS-VF dataset. 46 47 Args: 48 path: Filepath to a folder where the data is downloaded for further processing. 49 split: The choice of data split. 50 download: Whether to download the data if it is not present. 51 52 Returns: 53 Filepath where the data is downloaded. 54 """ 55 data_dir = os.path.join(path, f"BAGLS-VF_{split}") 56 if os.path.exists(data_dir): 57 return data_dir 58 59 os.makedirs(path, exist_ok=True) 60 61 zip_path = os.path.join(path, f"BAGLS-VF_{split}.zip") 62 util.download_source(path=zip_path, url=URLS[split], download=download, checksum=CHECKSUMS[split]) 63 util.unzip(zip_path=zip_path, dst=path) 64 65 return data_dir
Download the BAGLS-VF dataset.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- split: The choice of data split.
- download: Whether to download the data if it is not present.
Returns:
Filepath where the data is downloaded.
68def get_bagls_vf_paths( 69 path: Union[os.PathLike, str], split: Literal["train", "test"], download: bool = False 70) -> Tuple[List[str], List[str]]: 71 """Get paths to the BAGLS-VF data. 72 73 Args: 74 path: Filepath to a folder where the data is downloaded for further processing. 75 split: The choice of data split. 76 download: Whether to download the data if it is not present. 77 78 Returns: 79 List of filepaths for the image data. 80 List of filepaths for the label data. 81 """ 82 data_dir = get_bagls_vf_data(path=path, split=split, download=download) 83 84 image_paths = sorted(glob(os.path.join(data_dir, f"{split}_images", "*.png"))) 85 mask_dir = os.path.join(data_dir, f"{split}_masks") 86 87 neu_gt_dir = os.path.join(data_dir, "preprocessed_masks") 88 os.makedirs(neu_gt_dir, exist_ok=True) 89 90 gt_paths = [] 91 for image_path in image_paths: 92 fname = Path(image_path).stem 93 mask_path = os.path.join(mask_dir, f"{fname}.png") 94 neu_gt_path = os.path.join(neu_gt_dir, f"{fname}.tif") 95 gt_paths.append(neu_gt_path) 96 97 if os.path.exists(neu_gt_path): 98 continue 99 100 mask = imageio.imread(mask_path)[..., :3] 101 instances = np.zeros(mask.shape[:2], dtype="uint8") 102 for color, label in LABEL_MAP.items(): 103 if label == 0: 104 continue 105 binary_map = (mask == color).all(axis=-1) 106 instances[binary_map] = label 107 108 imageio.imwrite(neu_gt_path, instances, compression="zlib") 109 110 return image_paths, gt_paths
Get paths to the BAGLS-VF data.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- split: The choice of data split.
- download: Whether to download the data if it is not present.
Returns:
List of filepaths for the image data. List of filepaths for the label data.
113def get_bagls_vf_dataset( 114 path: Union[os.PathLike, str], 115 patch_shape: Tuple[int, int], 116 split: Literal["train", "test"], 117 resize_inputs: bool = False, 118 download: bool = False, 119 **kwargs 120) -> Dataset: 121 """Get the BAGLS-VF dataset for vocal fold and glottal area segmentation. 122 123 Args: 124 path: Filepath to a folder where the data is downloaded for further processing. 125 patch_shape: The patch shape to use for training. 126 split: The choice of data split. 127 resize_inputs: Whether to resize the inputs to the patch shape. 128 download: Whether to download the data if it is not present. 129 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 130 131 Returns: 132 The segmentation dataset. 133 """ 134 image_paths, gt_paths = get_bagls_vf_paths(path, split, download) 135 136 if resize_inputs: 137 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True} 138 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 139 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 140 ) 141 142 return torch_em.default_segmentation_dataset( 143 raw_paths=image_paths, 144 raw_key=None, 145 label_paths=gt_paths, 146 label_key=None, 147 patch_shape=patch_shape, 148 is_seg_dataset=False, 149 **kwargs 150 )
Get the BAGLS-VF dataset for vocal fold and glottal area segmentation.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- patch_shape: The patch shape to use for training.
- split: The choice of data split.
- resize_inputs: Whether to resize the inputs to the patch shape.
- download: Whether to download the data if it is not present.
- kwargs: Additional keyword arguments for
torch_em.default_segmentation_dataset.
Returns:
The segmentation dataset.
153def get_bagls_vf_loader( 154 path: Union[os.PathLike, str], 155 patch_shape: Tuple[int, int], 156 batch_size: int, 157 split: Literal["train", "test"], 158 resize_inputs: bool = False, 159 download: bool = False, 160 **kwargs 161) -> DataLoader: 162 """Get the BAGLS-VF dataloader for vocal fold and glottal area segmentation. 163 164 Args: 165 path: Filepath to a folder where the data is downloaded for further processing. 166 patch_shape: The patch shape to use for training. 167 batch_size: The batch size for training. 168 split: The choice of data split. 169 resize_inputs: Whether to resize the inputs to the patch shape. 170 download: Whether to download the data if it is not present. 171 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 172 173 Returns: 174 The DataLoader. 175 """ 176 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 177 dataset = get_bagls_vf_dataset(path, patch_shape, split, resize_inputs, download, **ds_kwargs) 178 return torch_em.get_data_loader(dataset=dataset, batch_size=batch_size, **loader_kwargs)
Get the BAGLS-VF dataloader for vocal fold and glottal area segmentation.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- patch_shape: The patch shape to use for training.
- batch_size: The batch size for training.
- split: The choice of data split.
- resize_inputs: Whether to resize the inputs to the patch shape.
- download: Whether to download the data if it is not present.
- kwargs: Additional keyword arguments for
torch_em.default_segmentation_datasetor for the PyTorch DataLoader.
Returns:
The DataLoader.