torch_em.data.datasets.medical.puwf_av
The PUWF-AV dataset contains annotations for artery-vein segmentation in pediatric ultra-widefield (UWF) fundus images.
For the class labels: red represents arteries, blue represents veins, green represents artery-vein crossings, and white represents vessels of uncertain classification.
NOTE: The dataset does not ship an official train / val / test split, so get_puwf_av_paths returns
all 60 images.
This dataset is from the publication https://doi.org/10.1038/s41597-026-08342-5. Please cite it if you use this dataset for your research.
1"""The PUWF-AV dataset contains annotations for artery-vein segmentation in pediatric 2ultra-widefield (UWF) fundus images. 3 4For the class labels: red represents arteries, blue represents veins, green represents artery-vein 5crossings, and white represents vessels of uncertain classification. 6 7NOTE: The dataset does not ship an official train / val / test split, so `get_puwf_av_paths` returns 8all 60 images. 9 10This dataset is from the publication https://doi.org/10.1038/s41597-026-08342-5. 11Please cite it if you use this dataset for your research. 12""" 13 14import os 15from glob import glob 16from pathlib import Path 17from natsort import natsorted 18from typing import Union, Tuple, List 19 20import numpy as np 21import imageio.v3 as imageio 22 23from torch.utils.data import Dataset, DataLoader 24 25import torch_em 26 27from .. import util 28 29 30URL = "https://ndownloader.figshare.com/files/65105883" 31CHECKSUM = "d8b9a060dde125e767f999de7cbfc8d49cfac584e22611d915c40e9ceb21a054" 32 33 34def _process_labels(data_dir): 35 label_paths = glob(os.path.join(data_dir, "annotation", "*.png")) 36 for label_path in label_paths: 37 labels = imageio.imread(label_path) 38 39 neu_labels = np.zeros(labels.shape[:2]) 40 neu_labels[np.all(labels == (255, 0, 0), axis=-1)] = 1 # red are arteries. 41 neu_labels[np.all(labels == (0, 0, 255), axis=-1)] = 2 # blue are veins. 42 neu_labels[np.all(labels == (0, 255, 0), axis=-1)] = 3 # green are overlaps. 43 neu_labels[np.all(labels == (255, 255, 255), axis=-1)] = 4 # white are unknown. 44 45 imageio.imwrite(Path(label_path).with_suffix(".tif"), neu_labels, compression="zlib") 46 47 os.remove(label_path) 48 49 50def get_puwf_av_data(path: Union[os.PathLike, str], download: bool = False) -> str: 51 """Download the PUWF-AV dataset. 52 53 Args: 54 path: Filepath to a folder where the data is downloaded for further processing. 55 download: Whether to download the data if it is not present. 56 57 Returns: 58 Filepath where the data is downloaded. 59 """ 60 data_dir = os.path.join(path, "PUWF-AV") 61 if os.path.exists(data_dir): 62 return data_dir 63 64 os.makedirs(path, exist_ok=True) 65 66 zip_path = os.path.join(path, "PUWF-AV.zip") 67 util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM) 68 util.unzip(zip_path=zip_path, dst=path) 69 70 _process_labels(data_dir) 71 72 return data_dir 73 74 75def get_puwf_av_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]: 76 """Get paths to the PUWF-AV data. 77 78 Args: 79 path: Filepath to a folder where the data is downloaded for further processing. 80 download: Whether to download the data if it is not present. 81 82 Returns: 83 List of filepaths for the image data. 84 List of filepaths for the label data. 85 """ 86 data_dir = get_puwf_av_data(path, download) 87 88 raw_paths = natsorted(glob(os.path.join(data_dir, "images", "*.png"))) 89 label_paths = natsorted(glob(os.path.join(data_dir, "annotation", "*.tif"))) 90 91 assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0 92 93 return raw_paths, label_paths 94 95 96def get_puwf_av_dataset( 97 path: Union[os.PathLike, str], 98 patch_shape: Tuple[int, int], 99 resize_inputs: bool = False, 100 download: bool = False, 101 **kwargs 102) -> Dataset: 103 """Get the PUWF-AV dataset for artery-vein segmentation. 104 105 Args: 106 path: Filepath to a folder where the data is downloaded for further processing. 107 patch_shape: The patch shape to use for training. 108 resize_inputs: Whether to resize the inputs to the patch shape. 109 download: Whether to download the data if it is not present. 110 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 111 112 Returns: 113 The segmentation dataset. 114 """ 115 raw_paths, label_paths = get_puwf_av_paths(path, download) 116 117 if resize_inputs: 118 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True} 119 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 120 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 121 ) 122 123 return torch_em.default_segmentation_dataset( 124 raw_paths=raw_paths, 125 raw_key=None, 126 label_paths=label_paths, 127 label_key=None, 128 is_seg_dataset=False, 129 patch_shape=patch_shape, 130 ndim=2, 131 **kwargs 132 ) 133 134 135def get_puwf_av_loader( 136 path: Union[os.PathLike, str], 137 batch_size: int, 138 patch_shape: Tuple[int, int], 139 resize_inputs: bool = False, 140 download: bool = False, 141 **kwargs 142) -> DataLoader: 143 """Get the PUWF-AV dataloader for artery-vein segmentation. 144 145 Args: 146 path: Filepath to a folder where the data is downloaded for further processing. 147 batch_size: The batch size for training. 148 patch_shape: The patch shape to use for training. 149 resize_inputs: Whether to resize the inputs to the patch shape. 150 download: Whether to download the data if it is not present. 151 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 152 153 Returns: 154 The DataLoader. 155 """ 156 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 157 dataset = get_puwf_av_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs) 158 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
51def get_puwf_av_data(path: Union[os.PathLike, str], download: bool = False) -> str: 52 """Download the PUWF-AV dataset. 53 54 Args: 55 path: Filepath to a folder where the data is downloaded for further processing. 56 download: Whether to download the data if it is not present. 57 58 Returns: 59 Filepath where the data is downloaded. 60 """ 61 data_dir = os.path.join(path, "PUWF-AV") 62 if os.path.exists(data_dir): 63 return data_dir 64 65 os.makedirs(path, exist_ok=True) 66 67 zip_path = os.path.join(path, "PUWF-AV.zip") 68 util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM) 69 util.unzip(zip_path=zip_path, dst=path) 70 71 _process_labels(data_dir) 72 73 return data_dir
Download the PUWF-AV dataset.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- download: Whether to download the data if it is not present.
Returns:
Filepath where the data is downloaded.
76def get_puwf_av_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]: 77 """Get paths to the PUWF-AV data. 78 79 Args: 80 path: Filepath to a folder where the data is downloaded for further processing. 81 download: Whether to download the data if it is not present. 82 83 Returns: 84 List of filepaths for the image data. 85 List of filepaths for the label data. 86 """ 87 data_dir = get_puwf_av_data(path, download) 88 89 raw_paths = natsorted(glob(os.path.join(data_dir, "images", "*.png"))) 90 label_paths = natsorted(glob(os.path.join(data_dir, "annotation", "*.tif"))) 91 92 assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0 93 94 return raw_paths, label_paths
Get paths to the PUWF-AV data.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- 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.
97def get_puwf_av_dataset( 98 path: Union[os.PathLike, str], 99 patch_shape: Tuple[int, int], 100 resize_inputs: bool = False, 101 download: bool = False, 102 **kwargs 103) -> Dataset: 104 """Get the PUWF-AV dataset for artery-vein segmentation. 105 106 Args: 107 path: Filepath to a folder where the data is downloaded for further processing. 108 patch_shape: The patch shape to use for training. 109 resize_inputs: Whether to resize the inputs to the patch shape. 110 download: Whether to download the data if it is not present. 111 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 112 113 Returns: 114 The segmentation dataset. 115 """ 116 raw_paths, label_paths = get_puwf_av_paths(path, download) 117 118 if resize_inputs: 119 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True} 120 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 121 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 122 ) 123 124 return torch_em.default_segmentation_dataset( 125 raw_paths=raw_paths, 126 raw_key=None, 127 label_paths=label_paths, 128 label_key=None, 129 is_seg_dataset=False, 130 patch_shape=patch_shape, 131 ndim=2, 132 **kwargs 133 )
Get the PUWF-AV dataset for artery-vein segmentation.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- patch_shape: The patch shape to use for training.
- 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.
136def get_puwf_av_loader( 137 path: Union[os.PathLike, str], 138 batch_size: int, 139 patch_shape: Tuple[int, int], 140 resize_inputs: bool = False, 141 download: bool = False, 142 **kwargs 143) -> DataLoader: 144 """Get the PUWF-AV dataloader for artery-vein segmentation. 145 146 Args: 147 path: Filepath to a folder where the data is downloaded for further processing. 148 batch_size: The batch size for training. 149 patch_shape: The patch shape to use for training. 150 resize_inputs: Whether to resize the inputs to the patch shape. 151 download: Whether to download the data if it is not present. 152 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 153 154 Returns: 155 The DataLoader. 156 """ 157 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 158 dataset = get_puwf_av_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs) 159 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
Get the PUWF-AV dataloader for artery-vein segmentation.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- batch_size: The batch size for training.
- patch_shape: The patch shape to use for training.
- 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.