torch_em.data.datasets.medical.ph2

The PH2 dataset contains annotations for skin lesion segmentation in dermoscopic images.

The dataset consists of 200 dermoscopic images acquired at the Dermatology Service of Hospital Pedro Hispano, Matosinhos, Portugal, together with binary lesion segmentation masks and a classification of dermoscopic criteria (e.g. common nevus, atypical nevus, melanoma).

The dataset is officially hosted at https://fc.up.pt/addi/ph2%20database.html, which requires filling out a registration form to obtain the download link. We instead use the mirror at https://www.kaggle.com/datasets/spacesurfer/ph2-dataset, which preserves the same folder layout as the original 'PH2Dataset.rar' archive.

This dataset is from the publication https://doi.org/10.1109/EMBC.2013.6610779. Please cite it if you use this dataset for your research.

  1"""The PH2 dataset contains annotations for skin lesion segmentation in dermoscopic images.
  2
  3The dataset consists of 200 dermoscopic images acquired at the Dermatology Service of Hospital
  4Pedro Hispano, Matosinhos, Portugal, together with binary lesion segmentation masks and a
  5classification of dermoscopic criteria (e.g. common nevus, atypical nevus, melanoma).
  6
  7The dataset is officially hosted at https://fc.up.pt/addi/ph2%20database.html, which requires
  8filling out a registration form to obtain the download link. We instead use the mirror at
  9https://www.kaggle.com/datasets/spacesurfer/ph2-dataset, which preserves the same folder layout
 10as the original 'PH2Dataset.rar' archive.
 11
 12This dataset is from the publication https://doi.org/10.1109/EMBC.2013.6610779.
 13Please cite it if you use this dataset for your research.
 14"""
 15
 16import os
 17from glob import glob
 18from natsort import natsorted
 19from typing import Union, Tuple, List
 20
 21from torch.utils.data import Dataset, DataLoader
 22
 23import torch_em
 24
 25from .. import util
 26
 27
 28KAGGLE_DATASET_NAME = "spacesurfer/ph2-dataset"
 29
 30
 31def get_ph2_data(path: Union[os.PathLike, str], download: bool = False) -> str:
 32    """Download the PH2 dataset.
 33
 34    Args:
 35        path: Filepath to a folder where the data is downloaded for further processing.
 36        download: Whether to download the data if it is not present.
 37
 38    Returns:
 39        Filepath where the data is downloaded.
 40    """
 41    data_dir = os.path.join(path, "PH2Dataset", "PH2 Dataset images")
 42    if os.path.exists(data_dir):
 43        return data_dir
 44
 45    os.makedirs(path, exist_ok=True)
 46
 47    util.download_source_kaggle(path=path, dataset_name=KAGGLE_DATASET_NAME, download=download)
 48
 49    zip_path = os.path.join(path, "ph2-dataset.zip")
 50    util.unzip(zip_path=zip_path, dst=path)
 51
 52    if not os.path.exists(data_dir):
 53        raise RuntimeError(f"The dataset could not be found at '{data_dir}' after extraction.")
 54
 55    return data_dir
 56
 57
 58def get_ph2_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
 59    """Get paths to the PH2 data.
 60
 61    Args:
 62        path: Filepath to a folder where the data is downloaded for further processing.
 63        download: Whether to download the data if it is not present.
 64
 65    Returns:
 66        List of filepaths for the image data.
 67        List of filepaths for the label data.
 68    """
 69    data_dir = get_ph2_data(path=path, download=download)
 70
 71    image_paths = natsorted(glob(os.path.join(data_dir, "*", "*_Dermoscopic_Image", "*.bmp")))
 72    gt_paths = natsorted(glob(os.path.join(data_dir, "*", "*_lesion", "*_lesion.bmp")))
 73
 74    if len(image_paths) == 0 or len(image_paths) != len(gt_paths):
 75        raise RuntimeError("Something went wrong with fetching the image and label paths.")
 76
 77    return image_paths, gt_paths
 78
 79
 80def get_ph2_dataset(
 81    path: Union[os.PathLike, str],
 82    patch_shape: Tuple[int, int],
 83    resize_inputs: bool = False,
 84    download: bool = False,
 85    **kwargs
 86) -> Dataset:
 87    """Get the PH2 dataset for skin lesion segmentation.
 88
 89    Args:
 90        path: Filepath to a folder where the data is downloaded for further processing.
 91        patch_shape: The patch shape to use for training.
 92        resize_inputs: Whether to resize the inputs.
 93        download: Whether to download the data if it is not present.
 94        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
 95
 96    Returns:
 97        The segmentation dataset.
 98    """
 99    image_paths, gt_paths = get_ph2_paths(path, download)
100
101    if resize_inputs:
102        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True}
103        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
104            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
105        )
106
107    return torch_em.default_segmentation_dataset(
108        raw_paths=image_paths,
109        raw_key=None,
110        label_paths=gt_paths,
111        label_key=None,
112        patch_shape=patch_shape,
113        is_seg_dataset=False,
114        **kwargs
115    )
116
117
118def get_ph2_loader(
119    path: Union[os.PathLike, str],
120    batch_size: int,
121    patch_shape: Tuple[int, int],
122    resize_inputs: bool = False,
123    download: bool = False,
124    **kwargs
125) -> DataLoader:
126    """Get the PH2 dataloader for skin lesion segmentation.
127
128    Args:
129        path: Filepath to a folder where the data is downloaded for further processing.
130        batch_size: The batch size for training.
131        patch_shape: The patch shape to use for training.
132        resize_inputs: Whether to resize the inputs.
133        download: Whether to download the data if it is not present.
134        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
135
136    Returns:
137        The DataLoader.
138    """
139    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
140    dataset = get_ph2_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs)
141    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
KAGGLE_DATASET_NAME = 'spacesurfer/ph2-dataset'
def get_ph2_data(path: Union[os.PathLike, str], download: bool = False) -> str:
32def get_ph2_data(path: Union[os.PathLike, str], download: bool = False) -> str:
33    """Download the PH2 dataset.
34
35    Args:
36        path: Filepath to a folder where the data is downloaded for further processing.
37        download: Whether to download the data if it is not present.
38
39    Returns:
40        Filepath where the data is downloaded.
41    """
42    data_dir = os.path.join(path, "PH2Dataset", "PH2 Dataset images")
43    if os.path.exists(data_dir):
44        return data_dir
45
46    os.makedirs(path, exist_ok=True)
47
48    util.download_source_kaggle(path=path, dataset_name=KAGGLE_DATASET_NAME, download=download)
49
50    zip_path = os.path.join(path, "ph2-dataset.zip")
51    util.unzip(zip_path=zip_path, dst=path)
52
53    if not os.path.exists(data_dir):
54        raise RuntimeError(f"The dataset could not be found at '{data_dir}' after extraction.")
55
56    return data_dir

Download the PH2 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.

def get_ph2_paths( path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
59def get_ph2_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
60    """Get paths to the PH2 data.
61
62    Args:
63        path: Filepath to a folder where the data is downloaded for further processing.
64        download: Whether to download the data if it is not present.
65
66    Returns:
67        List of filepaths for the image data.
68        List of filepaths for the label data.
69    """
70    data_dir = get_ph2_data(path=path, download=download)
71
72    image_paths = natsorted(glob(os.path.join(data_dir, "*", "*_Dermoscopic_Image", "*.bmp")))
73    gt_paths = natsorted(glob(os.path.join(data_dir, "*", "*_lesion", "*_lesion.bmp")))
74
75    if len(image_paths) == 0 or len(image_paths) != len(gt_paths):
76        raise RuntimeError("Something went wrong with fetching the image and label paths.")
77
78    return image_paths, gt_paths

Get paths to the PH2 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.

def get_ph2_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, int], resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
 81def get_ph2_dataset(
 82    path: Union[os.PathLike, str],
 83    patch_shape: Tuple[int, int],
 84    resize_inputs: bool = False,
 85    download: bool = False,
 86    **kwargs
 87) -> Dataset:
 88    """Get the PH2 dataset for skin lesion segmentation.
 89
 90    Args:
 91        path: Filepath to a folder where the data is downloaded for further processing.
 92        patch_shape: The patch shape to use for training.
 93        resize_inputs: Whether to resize the inputs.
 94        download: Whether to download the data if it is not present.
 95        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
 96
 97    Returns:
 98        The segmentation dataset.
 99    """
100    image_paths, gt_paths = get_ph2_paths(path, download)
101
102    if resize_inputs:
103        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True}
104        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
105            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
106        )
107
108    return torch_em.default_segmentation_dataset(
109        raw_paths=image_paths,
110        raw_key=None,
111        label_paths=gt_paths,
112        label_key=None,
113        patch_shape=patch_shape,
114        is_seg_dataset=False,
115        **kwargs
116    )

Get the PH2 dataset for skin lesion 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.
  • 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.

def get_ph2_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, int], resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
119def get_ph2_loader(
120    path: Union[os.PathLike, str],
121    batch_size: int,
122    patch_shape: Tuple[int, int],
123    resize_inputs: bool = False,
124    download: bool = False,
125    **kwargs
126) -> DataLoader:
127    """Get the PH2 dataloader for skin lesion segmentation.
128
129    Args:
130        path: Filepath to a folder where the data is downloaded for further processing.
131        batch_size: The batch size for training.
132        patch_shape: The patch shape to use for training.
133        resize_inputs: Whether to resize the inputs.
134        download: Whether to download the data if it is not present.
135        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
136
137    Returns:
138        The DataLoader.
139    """
140    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
141    dataset = get_ph2_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs)
142    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)

Get the PH2 dataloader for skin lesion 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.
  • download: Whether to download the data if it is not present.
  • kwargs: Additional keyword arguments for torch_em.default_segmentation_dataset or for the PyTorch DataLoader.
Returns:

The DataLoader.