torch_em.data.datasets.medical.hist_seg

The HIST-Seg dataset contains annotations for orthopedic tissue segmentation in hyperspectral surgical images.

The dataset consists of 220 hyperspectral cubes of ten bovine specimens (22 per specimen), acquired with a HinaLea camera in a simulated orthopedic surgery setting. Each cube has 299 spectral bands and 608 x 968 pixels and is paired with a pixel-wise semantic mask with the classes given in CLASS_NAMES. NOTE: The label ids follow the README of the dataset, so bone has the id 0 and there is no unlabeled id, the background of the operative field is class 6.

get_hist_seg_data converts every acquisition to a single hdf5 file. It contains the cube as 'raw' (bands first, shape (299, 608, 968), float32 reflectance) and the class map as 'labels' (shape (608, 968)). The masks are distributed as RGB images and are mapped to the class ids with the color table of the README.

The cubes are stored in one ~15.5 GB zip archive per specimen (~155 GB in total). To support downloading only a subset, single acquisitions are read from the archives with HTTP range requests (each member is verified with its CRC32) instead of downloading the archives as a whole. Use subjects or n_cases to select a subset.

NOTE: The dataset page sets a file access request flag, but the files are not restricted and can be downloaded anonymously.

The data is located at https://doi.org/10.57745/5N62WB, released under a CC-BY-4.0 license. The code of the authors is available at https://github.com/lsllabisen/HIST-Seg. Please cite the dataset if you use it for your research.

  1"""The HIST-Seg dataset contains annotations for orthopedic tissue segmentation in hyperspectral surgical images.
  2
  3The dataset consists of 220 hyperspectral cubes of ten bovine specimens (22 per specimen), acquired with a HinaLea
  4camera in a simulated orthopedic surgery setting. Each cube has 299 spectral bands and 608 x 968 pixels and is
  5paired with a pixel-wise semantic mask with the classes given in `CLASS_NAMES`. NOTE: The label ids follow the
  6README of the dataset, so bone has the id 0 and there is no unlabeled id, the background of the operative field is
  7class 6.
  8
  9`get_hist_seg_data` converts every acquisition to a single hdf5 file. It contains the cube as 'raw' (bands first, shape
 10(299, 608, 968), float32 reflectance) and the class map as 'labels' (shape (608, 968)). The masks are distributed as
 11RGB images and are mapped to the class ids with the color table of the README.
 12
 13The cubes are stored in one ~15.5 GB zip archive per specimen (~155 GB in total). To support downloading only a
 14subset, single acquisitions are read from the archives with HTTP range requests (each member is verified with its
 15CRC32) instead of downloading the archives as a whole. Use `subjects` or `n_cases` to select a subset.
 16
 17NOTE: The dataset page sets a file access request flag, but the files are not restricted and can be downloaded
 18anonymously.
 19
 20The data is located at https://doi.org/10.57745/5N62WB, released under a CC-BY-4.0 license.
 21The code of the authors is available at https://github.com/lsllabisen/HIST-Seg.
 22Please cite the dataset if you use it for your research.
 23"""
 24
 25import os
 26import json
 27import uuid
 28import zlib
 29import struct
 30from io import BytesIO
 31from natsort import natsorted
 32from concurrent import futures
 33from typing import Union, Tuple, List, Optional, Sequence
 34
 35import numpy as np
 36from tqdm import tqdm
 37
 38from torch.utils.data import Dataset, DataLoader
 39
 40import torch_em
 41
 42from .. import util
 43
 44
 45DATAFILE_URL = "https://entrepot.recherche.data.gouv.fr/api/access/datafile/{}"
 46DATAFILE_IDS = {
 47    "B0001": 717111, "B0002": 717113, "B0003": 717132, "B0004": 717414, "B0005": 717496,
 48    "B0006": 717582, "B0007": 717597, "B0008": 717786, "B0009": 717820, "B0010": 717893,
 49}
 50SUBJECTS = list(DATAFILE_IDS)
 51
 52CLASS_NAMES = ["bone", "cartilage", "ligament", "flesh", "fat", "instruments", "background"]
 53"""The names of the classes. The label id of a class is its index in this list."""
 54
 55COLORS = [
 56    (142, 223, 124), (111, 225, 243), (245, 245, 63), (246, 58, 90), (243, 172, 99), (168, 109, 109), (169, 169, 172),
 57]
 58BLOCK_SIZE = 64 * 1024 * 1024
 59
 60
 61def _resolve(datafile_id):
 62    import requests
 63
 64    headers = {"User-Agent": "Mozilla/5.0", "Range": "bytes=0-0"}
 65    response = requests.get(DATAFILE_URL.format(datafile_id), headers=headers, allow_redirects=True)
 66    response.raise_for_status()
 67    return response.url, int(response.headers["Content-Range"].split("/")[1])
 68
 69
 70def _get_range(url, start, end):
 71    import requests
 72
 73    response = requests.get(url, headers={"Range": f"bytes={start}-{end}"})
 74    response.raise_for_status()
 75    return response.content
 76
 77
 78def _read_zip_entries(url, size):
 79    tail = _get_range(url, size - 65536, size - 1)
 80    eocd = tail.rfind(b"PK\x05\x06")
 81    n_entries, cd_size, cd_offset = struct.unpack("<HII", tail[eocd + 10:eocd + 20])
 82    if n_entries == 0xFFFF or cd_offset == 0xFFFFFFFF:
 83        locator = tail.rfind(b"PK\x06\x07")
 84        zip64_offset = struct.unpack("<Q", tail[locator + 8:locator + 16])[0]
 85        zip64 = _get_range(url, zip64_offset, zip64_offset + 55)
 86        n_entries, cd_size, cd_offset = struct.unpack("<QQQ", zip64[32:56])
 87    directory = _get_range(url, cd_offset, cd_offset + cd_size - 1)
 88
 89    entries, pos = {}, 0
 90    for _ in range(n_entries):
 91        fields = struct.unpack("<IHHHHHHIIIHHHHHII", directory[pos:pos + 46])
 92        method, crc, csize, usize = fields[4], fields[7], fields[8], fields[9]
 93        name_len, extra_len, comment_len = fields[10], fields[11], fields[12]
 94        header_offset = fields[16]
 95        name = directory[pos + 46:pos + 46 + name_len].decode()
 96        extra = directory[pos + 46 + name_len:pos + 46 + name_len + extra_len]
 97        offset = 0
 98        while offset < len(extra):
 99            tag, field_size = struct.unpack("<HH", extra[offset:offset + 4])
100            if tag == 1:
101                field, field_pos = extra[offset + 4:offset + 4 + field_size], 0
102                if usize == 0xFFFFFFFF:
103                    usize, field_pos = struct.unpack("<Q", field[field_pos:field_pos + 8])[0], field_pos + 8
104                if csize == 0xFFFFFFFF:
105                    csize, field_pos = struct.unpack("<Q", field[field_pos:field_pos + 8])[0], field_pos + 8
106                if header_offset == 0xFFFFFFFF:
107                    header_offset = struct.unpack("<Q", field[field_pos:field_pos + 8])[0]
108            offset += 4 + field_size
109        entries[name] = {"method": method, "crc": crc, "compressed_size": csize, "header_offset": header_offset}
110        pos += 46 + name_len + extra_len + comment_len
111
112    return entries
113
114
115def _get_entries(path, subject, download):
116    cache_path = os.path.join(path, f"entries_{subject}.json")
117    if os.path.exists(cache_path):
118        with open(cache_path) as f:
119            return json.load(f)
120
121    if not download:
122        raise RuntimeError(f"Cannot find the data at {path}, but download was set to False.")
123
124    url, size = _resolve(DATAFILE_IDS[subject])
125    entries = _read_zip_entries(url, size)
126    tmp_path = f"{cache_path}.{uuid.uuid4().hex}.incomplete"
127    with open(tmp_path, "w") as f:
128        json.dump(entries, f)
129    os.replace(tmp_path, cache_path)
130    return entries
131
132
133def _read_zip_member(url, entry):
134    offset = entry["header_offset"]
135    header = _get_range(url, offset, offset + 29)
136    name_len, extra_len = struct.unpack("<HH", header[26:30])
137    start = offset + 30 + name_len + extra_len
138
139    chunks = []
140    for block_start in range(0, entry["compressed_size"], BLOCK_SIZE):
141        block_end = min(block_start + BLOCK_SIZE, entry["compressed_size"]) - 1
142        chunks.append(_get_range(url, start + block_start, start + block_end))
143    data = b"".join(chunks)
144
145    if entry["method"] == 8:
146        data = zlib.decompress(data, -15)
147    if zlib.crc32(data) != entry["crc"]:
148        raise RuntimeError("The checksum of a downloaded archive member does not match.")
149    return data
150
151
152def _parse_header(header):
153    fields = {}
154    for line in header.decode(errors="replace").splitlines():
155        if "=" in line:
156            key, value = line.split("=", 1)
157            fields[key.strip()] = value.strip()
158    assert fields["interleave"] == "bsq" and fields["data type"] == "4" and fields["byte order"] == "0", fields
159    return int(fields["bands"]), int(fields["lines"]), int(fields["samples"])
160
161
162def _mask_to_labels(mask):
163    encoded = (mask[..., 0].astype("uint32") << 16) | (mask[..., 1].astype("uint32") << 8) | mask[..., 2]
164    labels = np.full(encoded.shape, 255, dtype="uint8")
165    for class_id, (r, g, b) in enumerate(COLORS):
166        labels[encoded == ((r << 16) | (g << 8) | b)] = class_id
167    assert (labels != 255).all(), "The mask contains a color that does not belong to a class."
168    return labels
169
170
171def _convert_acquisition(subject, acquisition, path, entries):
172    import h5py
173    from PIL import Image
174
175    out_path = os.path.join(path, "preprocessed", f"{acquisition}.h5")
176    if os.path.exists(out_path):
177        return
178
179    url, _ = _resolve(DATAFILE_IDS[subject])
180    prefix = f"{subject}/{acquisition}"
181    bands, lines, samples = _parse_header(_read_zip_member(url, entries[f"{prefix}/{acquisition}.hdr"]))
182    cube = np.frombuffer(_read_zip_member(url, entries[f"{prefix}/{acquisition}.dat"]), dtype="<f4")
183    cube = cube.reshape(bands, lines, samples)
184
185    mask = np.array(Image.open(BytesIO(_read_zip_member(url, entries[f"{prefix}/Annotations/{acquisition}.png"]))))
186    labels = _mask_to_labels(mask[..., :3])
187    assert labels.shape == cube.shape[1:], f"{acquisition}: {labels.shape} != {cube.shape[1:]}"
188
189    tmp_path = f"{out_path}.{uuid.uuid4().hex}.incomplete"
190    with h5py.File(tmp_path, "w") as f:
191        f.create_dataset("raw", data=cube, chunks=(bands, 64, 64), compression="gzip")
192        f.create_dataset("labels", data=labels, chunks=(64, 64), compression="gzip")
193    os.replace(tmp_path, out_path)
194
195
196def _list_acquisitions(path, subjects, n_cases, download):
197    acquisitions = []
198    for subject in subjects:
199        entries = _get_entries(path, subject, download)
200        names = natsorted({name.split("/")[1] for name in entries if name.endswith(".dat")})
201        acquisitions.extend(
202            (subject, name) for name in names if f"{subject}/{name}/Annotations/{name}.png" in entries
203        )
204        if n_cases is not None and len(acquisitions) >= n_cases:
205            break
206    return acquisitions[:n_cases]
207
208
209def get_hist_seg_data(
210    path: Union[os.PathLike, str],
211    subjects: Optional[Sequence[str]] = None,
212    n_cases: Optional[int] = None,
213    n_workers: int = 2,
214    download: bool = False,
215) -> str:
216    """Download the HIST-Seg dataset and convert the acquisitions to hdf5 files.
217
218    NOTE: The full collection is about 155 GB. Use `subjects` or `n_cases` to only download a subset.
219
220    Args:
221        path: Filepath to a folder where the data is downloaded for further processing.
222        subjects: The specimens to use, a subset of `SUBJECTS`. By default all ten specimens are used.
223        n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
224        n_workers: The number of parallel download and conversion workers. Each worker holds a cube of ~0.7 GB.
225        download: Whether to download the data if it is not present.
226
227    Returns:
228        Filepath to the folder with the converted hdf5 files.
229    """
230    subjects = SUBJECTS if subjects is None else list(subjects)
231    invalid = [s for s in subjects if s not in DATAFILE_IDS]
232    if invalid:
233        raise ValueError(f"{invalid} are not valid subjects. Choose from {SUBJECTS}.")
234
235    os.makedirs(path, exist_ok=True)
236    preprocessed_dir = os.path.join(path, "preprocessed")
237    acquisitions = _list_acquisitions(path, subjects, n_cases, download)
238
239    missing = [(s, a) for s, a in acquisitions if not os.path.exists(os.path.join(preprocessed_dir, f"{a}.h5"))]
240    if not missing:
241        return preprocessed_dir
242    if not download:
243        raise RuntimeError(f"Cannot find the data at {path}, but download was set to False.")
244
245    os.makedirs(preprocessed_dir, exist_ok=True)
246    entries = {subject: _get_entries(path, subject, download) for subject in {s for s, _ in missing}}
247    with futures.ThreadPoolExecutor(n_workers) as pool:
248        tasks = [pool.submit(_convert_acquisition, s, a, path, entries[s]) for s, a in missing]
249        for task in tqdm(futures.as_completed(tasks), total=len(tasks), desc="Download and convert HIST-Seg"):
250            task.result()
251
252    return preprocessed_dir
253
254
255def get_hist_seg_paths(
256    path: Union[os.PathLike, str],
257    subjects: Optional[Sequence[str]] = None,
258    n_cases: Optional[int] = None,
259    download: bool = False,
260) -> List[str]:
261    """Get paths to the HIST-Seg data.
262
263    Args:
264        path: Filepath to a folder where the data is downloaded for further processing.
265        subjects: The specimens to use, a subset of `SUBJECTS`. By default all ten specimens are used.
266        n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
267        download: Whether to download the data if it is not present.
268
269    Returns:
270        List of filepaths for the hdf5 files, which contain the cubes ('raw') and the class maps ('labels').
271    """
272    subjects = SUBJECTS if subjects is None else list(subjects)
273    preprocessed_dir = get_hist_seg_data(path, subjects, n_cases, download=download)
274    acquisitions = _list_acquisitions(path, subjects, n_cases, download)
275    return [os.path.join(preprocessed_dir, f"{a}.h5") for _, a in acquisitions]
276
277
278def get_hist_seg_dataset(
279    path: Union[os.PathLike, str],
280    patch_shape: Tuple[int, int],
281    subjects: Optional[Sequence[str]] = None,
282    n_cases: Optional[int] = None,
283    download: bool = False,
284    **kwargs
285) -> Dataset:
286    """Get the HIST-Seg dataset for tissue segmentation in hyperspectral surgical images.
287
288    The raw data has 299 channels (the spectral bands), the labels are the class ids of `CLASS_NAMES`.
289
290    Args:
291        path: Filepath to a folder where the data is downloaded for further processing.
292        patch_shape: The patch shape to use for training.
293        subjects: The specimens to use, a subset of `SUBJECTS`. By default all ten specimens are used.
294        n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
295        download: Whether to download the data if it is not present.
296        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
297
298    Returns:
299        The segmentation dataset.
300    """
301    volume_paths = get_hist_seg_paths(path, subjects, n_cases, download)
302
303    return torch_em.default_segmentation_dataset(
304        raw_paths=volume_paths,
305        raw_key="raw",
306        label_paths=volume_paths,
307        label_key="labels",
308        patch_shape=patch_shape,
309        is_seg_dataset=True,
310        with_channels=True,
311        ndim=2,
312        **kwargs
313    )
314
315
316def get_hist_seg_loader(
317    path: Union[os.PathLike, str],
318    batch_size: int,
319    patch_shape: Tuple[int, int],
320    subjects: Optional[Sequence[str]] = None,
321    n_cases: Optional[int] = None,
322    download: bool = False,
323    **kwargs
324) -> DataLoader:
325    """Get the HIST-Seg dataloader for tissue segmentation in hyperspectral surgical images.
326
327    Args:
328        path: Filepath to a folder where the data is downloaded for further processing.
329        batch_size: The batch size for training.
330        patch_shape: The patch shape to use for training.
331        subjects: The specimens to use, a subset of `SUBJECTS`. By default all ten specimens are used.
332        n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
333        download: Whether to download the data if it is not present.
334        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
335
336    Returns:
337        The DataLoader.
338    """
339    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
340    dataset = get_hist_seg_dataset(path, patch_shape, subjects, n_cases, download, **ds_kwargs)
341    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
DATAFILE_URL = 'https://entrepot.recherche.data.gouv.fr/api/access/datafile/{}'
DATAFILE_IDS = {'B0001': 717111, 'B0002': 717113, 'B0003': 717132, 'B0004': 717414, 'B0005': 717496, 'B0006': 717582, 'B0007': 717597, 'B0008': 717786, 'B0009': 717820, 'B0010': 717893}
SUBJECTS = ['B0001', 'B0002', 'B0003', 'B0004', 'B0005', 'B0006', 'B0007', 'B0008', 'B0009', 'B0010']
CLASS_NAMES = ['bone', 'cartilage', 'ligament', 'flesh', 'fat', 'instruments', 'background']

The names of the classes. The label id of a class is its index in this list.

COLORS = [(142, 223, 124), (111, 225, 243), (245, 245, 63), (246, 58, 90), (243, 172, 99), (168, 109, 109), (169, 169, 172)]
BLOCK_SIZE = 67108864
def get_hist_seg_data( path: Union[os.PathLike, str], subjects: Optional[Sequence[str]] = None, n_cases: Optional[int] = None, n_workers: int = 2, download: bool = False) -> str:
210def get_hist_seg_data(
211    path: Union[os.PathLike, str],
212    subjects: Optional[Sequence[str]] = None,
213    n_cases: Optional[int] = None,
214    n_workers: int = 2,
215    download: bool = False,
216) -> str:
217    """Download the HIST-Seg dataset and convert the acquisitions to hdf5 files.
218
219    NOTE: The full collection is about 155 GB. Use `subjects` or `n_cases` to only download a subset.
220
221    Args:
222        path: Filepath to a folder where the data is downloaded for further processing.
223        subjects: The specimens to use, a subset of `SUBJECTS`. By default all ten specimens are used.
224        n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
225        n_workers: The number of parallel download and conversion workers. Each worker holds a cube of ~0.7 GB.
226        download: Whether to download the data if it is not present.
227
228    Returns:
229        Filepath to the folder with the converted hdf5 files.
230    """
231    subjects = SUBJECTS if subjects is None else list(subjects)
232    invalid = [s for s in subjects if s not in DATAFILE_IDS]
233    if invalid:
234        raise ValueError(f"{invalid} are not valid subjects. Choose from {SUBJECTS}.")
235
236    os.makedirs(path, exist_ok=True)
237    preprocessed_dir = os.path.join(path, "preprocessed")
238    acquisitions = _list_acquisitions(path, subjects, n_cases, download)
239
240    missing = [(s, a) for s, a in acquisitions if not os.path.exists(os.path.join(preprocessed_dir, f"{a}.h5"))]
241    if not missing:
242        return preprocessed_dir
243    if not download:
244        raise RuntimeError(f"Cannot find the data at {path}, but download was set to False.")
245
246    os.makedirs(preprocessed_dir, exist_ok=True)
247    entries = {subject: _get_entries(path, subject, download) for subject in {s for s, _ in missing}}
248    with futures.ThreadPoolExecutor(n_workers) as pool:
249        tasks = [pool.submit(_convert_acquisition, s, a, path, entries[s]) for s, a in missing]
250        for task in tqdm(futures.as_completed(tasks), total=len(tasks), desc="Download and convert HIST-Seg"):
251            task.result()
252
253    return preprocessed_dir

Download the HIST-Seg dataset and convert the acquisitions to hdf5 files.

NOTE: The full collection is about 155 GB. Use subjects or n_cases to only download a subset.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • subjects: The specimens to use, a subset of SUBJECTS. By default all ten specimens are used.
  • n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
  • n_workers: The number of parallel download and conversion workers. Each worker holds a cube of ~0.7 GB.
  • download: Whether to download the data if it is not present.
Returns:

Filepath to the folder with the converted hdf5 files.

def get_hist_seg_paths( path: Union[os.PathLike, str], subjects: Optional[Sequence[str]] = None, n_cases: Optional[int] = None, download: bool = False) -> List[str]:
256def get_hist_seg_paths(
257    path: Union[os.PathLike, str],
258    subjects: Optional[Sequence[str]] = None,
259    n_cases: Optional[int] = None,
260    download: bool = False,
261) -> List[str]:
262    """Get paths to the HIST-Seg data.
263
264    Args:
265        path: Filepath to a folder where the data is downloaded for further processing.
266        subjects: The specimens to use, a subset of `SUBJECTS`. By default all ten specimens are used.
267        n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
268        download: Whether to download the data if it is not present.
269
270    Returns:
271        List of filepaths for the hdf5 files, which contain the cubes ('raw') and the class maps ('labels').
272    """
273    subjects = SUBJECTS if subjects is None else list(subjects)
274    preprocessed_dir = get_hist_seg_data(path, subjects, n_cases, download=download)
275    acquisitions = _list_acquisitions(path, subjects, n_cases, download)
276    return [os.path.join(preprocessed_dir, f"{a}.h5") for _, a in acquisitions]

Get paths to the HIST-Seg data.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • subjects: The specimens to use, a subset of SUBJECTS. By default all ten specimens are used.
  • n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
  • download: Whether to download the data if it is not present.
Returns:

List of filepaths for the hdf5 files, which contain the cubes ('raw') and the class maps ('labels').

def get_hist_seg_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, int], subjects: Optional[Sequence[str]] = None, n_cases: Optional[int] = None, download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
279def get_hist_seg_dataset(
280    path: Union[os.PathLike, str],
281    patch_shape: Tuple[int, int],
282    subjects: Optional[Sequence[str]] = None,
283    n_cases: Optional[int] = None,
284    download: bool = False,
285    **kwargs
286) -> Dataset:
287    """Get the HIST-Seg dataset for tissue segmentation in hyperspectral surgical images.
288
289    The raw data has 299 channels (the spectral bands), the labels are the class ids of `CLASS_NAMES`.
290
291    Args:
292        path: Filepath to a folder where the data is downloaded for further processing.
293        patch_shape: The patch shape to use for training.
294        subjects: The specimens to use, a subset of `SUBJECTS`. By default all ten specimens are used.
295        n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
296        download: Whether to download the data if it is not present.
297        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
298
299    Returns:
300        The segmentation dataset.
301    """
302    volume_paths = get_hist_seg_paths(path, subjects, n_cases, download)
303
304    return torch_em.default_segmentation_dataset(
305        raw_paths=volume_paths,
306        raw_key="raw",
307        label_paths=volume_paths,
308        label_key="labels",
309        patch_shape=patch_shape,
310        is_seg_dataset=True,
311        with_channels=True,
312        ndim=2,
313        **kwargs
314    )

Get the HIST-Seg dataset for tissue segmentation in hyperspectral surgical images.

The raw data has 299 channels (the spectral bands), the labels are the class ids of CLASS_NAMES.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • patch_shape: The patch shape to use for training.
  • subjects: The specimens to use, a subset of SUBJECTS. By default all ten specimens are used.
  • n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
  • 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_hist_seg_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, int], subjects: Optional[Sequence[str]] = None, n_cases: Optional[int] = None, download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
317def get_hist_seg_loader(
318    path: Union[os.PathLike, str],
319    batch_size: int,
320    patch_shape: Tuple[int, int],
321    subjects: Optional[Sequence[str]] = None,
322    n_cases: Optional[int] = None,
323    download: bool = False,
324    **kwargs
325) -> DataLoader:
326    """Get the HIST-Seg dataloader for tissue segmentation in hyperspectral surgical images.
327
328    Args:
329        path: Filepath to a folder where the data is downloaded for further processing.
330        batch_size: The batch size for training.
331        patch_shape: The patch shape to use for training.
332        subjects: The specimens to use, a subset of `SUBJECTS`. By default all ten specimens are used.
333        n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
334        download: Whether to download the data if it is not present.
335        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
336
337    Returns:
338        The DataLoader.
339    """
340    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
341    dataset = get_hist_seg_dataset(path, patch_shape, subjects, n_cases, download, **ds_kwargs)
342    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)

Get the HIST-Seg dataloader for tissue segmentation in hyperspectral surgical images.

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.
  • subjects: The specimens to use, a subset of SUBJECTS. By default all ten specimens are used.
  • n_cases: The number of acquisitions to use, sorted by specimen and acquisition id. By default all are used.
  • 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.