torch_em.data.datasets.medical.sts2024
The STS2024 dataset contains annotations for instance-level tooth segmentation, labeled by FDI tooth id, in panoramic dental X-rays (OPGs).
The dataset was curated for the 2nd Semi-supervised Teeth Segmentation (STS 2024) MICCAI challenge (https://sts-challenge.github.io/miccai2024/index.html), which extends the STS 2023 challenge to multi-instance, multi-class (FDI enumeration) instance-level tooth segmentation in both panoramic X-rays and CBCT scans. The full challenge data comprises 2,380 OPGs and 330 CBCT volumes, but only 30 OPG cases and 30 CBCT cases carry full ground truth (the remaining images support the challenge's semi-supervised learning setting and have no public labels). This module only covers the 30 fully labeled OPG cases, released on Zenodo; the CBCT ground truth is not part of that release.
The original annotations are per-tooth polygons (in labelme format) with the FDI tooth id as the label; this module rasterizes them into a per-pixel label map, where the pixel value is the FDI id of the tooth (0 marks background).
The data is hosted on Zenodo at https://zenodo.org/records/17712688 and is distributed under the CC BY 4.0 license.
The dataset is from the publication https://doi.org/10.1016/j.media.2026.103986. Please cite it if you use this dataset for your research.
1"""The STS2024 dataset contains annotations for instance-level tooth segmentation, labeled by 2FDI tooth id, in panoramic dental X-rays (OPGs). 3 4The dataset was curated for the 2nd Semi-supervised Teeth Segmentation (STS 2024) MICCAI challenge 5(https://sts-challenge.github.io/miccai2024/index.html), which extends the STS 2023 challenge to 6multi-instance, multi-class (FDI enumeration) instance-level tooth segmentation in both panoramic 7X-rays and CBCT scans. The full challenge data comprises 2,380 OPGs and 330 CBCT volumes, but only 830 OPG cases and 30 CBCT cases carry full ground truth (the remaining images support the challenge's 9semi-supervised learning setting and have no public labels). This module only covers the 30 fully 10labeled OPG cases, released on Zenodo; the CBCT ground truth is not part of that release. 11 12The original annotations are per-tooth polygons (in labelme format) with the FDI tooth id as the 13label; this module rasterizes them into a per-pixel label map, where the pixel value is the FDI id 14of the tooth (0 marks background). 15 16The data is hosted on Zenodo at https://zenodo.org/records/17712688 and is distributed under the 17CC BY 4.0 license. 18 19The dataset is from the publication https://doi.org/10.1016/j.media.2026.103986. 20Please cite it if you use this dataset for your research. 21""" 22 23import os 24import json 25from glob import glob 26from tqdm import tqdm 27from natsort import natsorted 28from typing import Union, Tuple, List 29 30import numpy as np 31from skimage.draw import polygon 32 33import imageio.v3 as imageio 34 35from torch.utils.data import Dataset, DataLoader 36 37import torch_em 38 39from .. import util 40 41 42URL = "https://zenodo.org/records/17712688/files/Train-Labeled.zip?download=1" 43CHECKSUM = "8d0e1491368f15c770f592d6c9284861629140e6bb550659257a3ff13b4b9761" 44 45 46def get_sts2024_data(path: Union[os.PathLike, str], download: bool = False) -> str: 47 """Download the STS2024 dataset. 48 49 Args: 50 path: Filepath to a folder where the data is downloaded for further processing. 51 download: Whether to download the data if it is not present. 52 53 Returns: 54 Filepath where the data is downloaded. 55 """ 56 data_dir = os.path.join(path, "Train-Labeled") 57 if os.path.exists(data_dir): 58 return data_dir 59 60 os.makedirs(path, exist_ok=True) 61 zip_path = os.path.join(path, "Train-Labeled.zip") 62 util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM) 63 util.unzip(zip_path=zip_path, dst=path) 64 65 return data_dir 66 67 68def _rasterize_annotations(shape, annotation_path): 69 with open(annotation_path) as f: 70 annotations = json.load(f) 71 72 labels = np.zeros(shape, dtype="uint8") 73 for shape_annotation in annotations["shapes"]: 74 fdi_id = int(shape_annotation["label"]) 75 points = np.asarray(shape_annotation["points"]) 76 c, r = points[:, 0], points[:, 1] 77 rr, cc = polygon(r, c, shape=shape) 78 labels[rr, cc] = fdi_id 79 80 return labels 81 82 83def get_sts2024_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]: 84 """Get paths to the STS2024 data. 85 86 Args: 87 path: Filepath to a folder where the data is downloaded for further processing. 88 download: Whether to download the data if it is not present. 89 90 Returns: 91 List of filepaths for the image data. 92 List of filepaths for the label data. 93 """ 94 data_dir = get_sts2024_data(path, download) 95 96 image_dir = os.path.join(data_dir, "Images") 97 annotation_dir = os.path.join(data_dir, "Masks") 98 preprocessed_dir = os.path.join(data_dir, "preprocessed") 99 os.makedirs(preprocessed_dir, exist_ok=True) 100 101 image_paths = natsorted(glob(os.path.join(image_dir, "*.jpg"))) 102 103 gt_paths = [] 104 for image_path in tqdm(image_paths, desc="Preprocessing labels"): 105 fname = os.path.splitext(os.path.basename(image_path))[0] 106 annotation_path = os.path.join(annotation_dir, f"{fname}_Mask.json") 107 gt_path = os.path.join(preprocessed_dir, f"{fname}.tif") 108 109 if not os.path.exists(gt_path): 110 image_shape = imageio.imread(image_path).shape[:2] 111 labels = _rasterize_annotations(image_shape, annotation_path) 112 imageio.imwrite(gt_path, labels) 113 114 gt_paths.append(gt_path) 115 116 return image_paths, gt_paths 117 118 119def get_sts2024_dataset( 120 path: Union[os.PathLike, str], 121 patch_shape: Tuple[int, int], 122 resize_inputs: bool = False, 123 download: bool = False, 124 **kwargs 125) -> Dataset: 126 """Get the STS2024 dataset for FDI tooth segmentation in panoramic dental radiographs. 127 128 Args: 129 path: Filepath to a folder where the data is downloaded for further processing. 130 patch_shape: The patch shape to use for training. 131 resize_inputs: Whether to resize the inputs to the patch shape. 132 download: Whether to download the data if it is not present. 133 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 134 135 Returns: 136 The segmentation dataset. 137 """ 138 image_paths, gt_paths = get_sts2024_paths(path, download) 139 140 if resize_inputs: 141 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False} 142 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 143 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 144 ) 145 146 return torch_em.default_segmentation_dataset( 147 raw_paths=image_paths, 148 raw_key=None, 149 label_paths=gt_paths, 150 label_key=None, 151 is_seg_dataset=False, 152 patch_shape=patch_shape, 153 **kwargs 154 ) 155 156 157def get_sts2024_loader( 158 path: Union[os.PathLike, str], 159 batch_size: int, 160 patch_shape: Tuple[int, int], 161 resize_inputs: bool = False, 162 download: bool = False, 163 **kwargs 164) -> DataLoader: 165 """Get the STS2024 dataloader for FDI tooth segmentation in panoramic dental radiographs. 166 167 Args: 168 path: Filepath to a folder where the data is downloaded for further processing. 169 batch_size: The batch size for training. 170 patch_shape: The patch shape to use for training. 171 resize_inputs: Whether to resize the inputs to the patch shape. 172 download: Whether to download the data if it is not present. 173 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 174 175 Returns: 176 The DataLoader. 177 """ 178 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 179 dataset = get_sts2024_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs) 180 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
47def get_sts2024_data(path: Union[os.PathLike, str], download: bool = False) -> str: 48 """Download the STS2024 dataset. 49 50 Args: 51 path: Filepath to a folder where the data is downloaded for further processing. 52 download: Whether to download the data if it is not present. 53 54 Returns: 55 Filepath where the data is downloaded. 56 """ 57 data_dir = os.path.join(path, "Train-Labeled") 58 if os.path.exists(data_dir): 59 return data_dir 60 61 os.makedirs(path, exist_ok=True) 62 zip_path = os.path.join(path, "Train-Labeled.zip") 63 util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM) 64 util.unzip(zip_path=zip_path, dst=path) 65 66 return data_dir
Download the STS2024 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.
84def get_sts2024_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]: 85 """Get paths to the STS2024 data. 86 87 Args: 88 path: Filepath to a folder where the data is downloaded for further processing. 89 download: Whether to download the data if it is not present. 90 91 Returns: 92 List of filepaths for the image data. 93 List of filepaths for the label data. 94 """ 95 data_dir = get_sts2024_data(path, download) 96 97 image_dir = os.path.join(data_dir, "Images") 98 annotation_dir = os.path.join(data_dir, "Masks") 99 preprocessed_dir = os.path.join(data_dir, "preprocessed") 100 os.makedirs(preprocessed_dir, exist_ok=True) 101 102 image_paths = natsorted(glob(os.path.join(image_dir, "*.jpg"))) 103 104 gt_paths = [] 105 for image_path in tqdm(image_paths, desc="Preprocessing labels"): 106 fname = os.path.splitext(os.path.basename(image_path))[0] 107 annotation_path = os.path.join(annotation_dir, f"{fname}_Mask.json") 108 gt_path = os.path.join(preprocessed_dir, f"{fname}.tif") 109 110 if not os.path.exists(gt_path): 111 image_shape = imageio.imread(image_path).shape[:2] 112 labels = _rasterize_annotations(image_shape, annotation_path) 113 imageio.imwrite(gt_path, labels) 114 115 gt_paths.append(gt_path) 116 117 return image_paths, gt_paths
Get paths to the STS2024 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.
120def get_sts2024_dataset( 121 path: Union[os.PathLike, str], 122 patch_shape: Tuple[int, int], 123 resize_inputs: bool = False, 124 download: bool = False, 125 **kwargs 126) -> Dataset: 127 """Get the STS2024 dataset for FDI tooth segmentation in panoramic dental radiographs. 128 129 Args: 130 path: Filepath to a folder where the data is downloaded for further processing. 131 patch_shape: The patch shape to use for training. 132 resize_inputs: Whether to resize the inputs to the patch shape. 133 download: Whether to download the data if it is not present. 134 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 135 136 Returns: 137 The segmentation dataset. 138 """ 139 image_paths, gt_paths = get_sts2024_paths(path, download) 140 141 if resize_inputs: 142 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False} 143 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 144 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 145 ) 146 147 return torch_em.default_segmentation_dataset( 148 raw_paths=image_paths, 149 raw_key=None, 150 label_paths=gt_paths, 151 label_key=None, 152 is_seg_dataset=False, 153 patch_shape=patch_shape, 154 **kwargs 155 )
Get the STS2024 dataset for FDI tooth segmentation in panoramic dental radiographs.
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.
158def get_sts2024_loader( 159 path: Union[os.PathLike, str], 160 batch_size: int, 161 patch_shape: Tuple[int, int], 162 resize_inputs: bool = False, 163 download: bool = False, 164 **kwargs 165) -> DataLoader: 166 """Get the STS2024 dataloader for FDI tooth segmentation in panoramic dental radiographs. 167 168 Args: 169 path: Filepath to a folder where the data is downloaded for further processing. 170 batch_size: The batch size for training. 171 patch_shape: The patch shape to use for training. 172 resize_inputs: Whether to resize the inputs to the patch shape. 173 download: Whether to download the data if it is not present. 174 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 175 176 Returns: 177 The DataLoader. 178 """ 179 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 180 dataset = get_sts2024_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs) 181 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
Get the STS2024 dataloader for FDI tooth segmentation in panoramic dental radiographs.
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.