xiazhi1
initial commit
aea73e2
raw
history blame
3.89 kB
# -*- coding: utf-8 -*-
# MoNuSeg Dataset
#
# Dataset information: https://monuseg.grand-challenge.org/Home/
# Please Prepare Dataset as described here: docs/readmes/monuseg.md
#
# @ Fabian Hörst, fabian.hoerst@uk-essen.de
# Institute for Artifical Intelligence in Medicine,
# University Medicine Essen
import logging
from pathlib import Path
from typing import Callable, Union, Tuple
import numpy as np
import torch
from PIL import Image
from torch.utils.data import Dataset
from cell_segmentation.datasets.pannuke import PanNukeDataset
logger = logging.getLogger()
logger.addHandler(logging.NullHandler())
class CoNSePDataset(Dataset):
def __init__(
self,
dataset_path: Union[Path, str],
transforms: Callable = None,
) -> None:
"""MoNuSeg Dataset
Args:
dataset_path (Union[Path, str]): Path to dataset
transforms (Callable, optional): Transformations to apply on images. Defaults to None.
Raises:
FileNotFoundError: If no ground-truth annotation file was found in path
"""
self.dataset = Path(dataset_path).resolve()
self.transforms = transforms
self.masks = []
self.img_names = []
image_path = self.dataset / "images"
label_path = self.dataset / "labels"
self.images = [f for f in sorted(image_path.glob("*.png")) if f.is_file()]
self.masks = [f for f in sorted(label_path.glob("*.npy")) if f.is_file()]
# sanity_check
for idx, image in enumerate(self.images):
image_name = image.stem
mask_name = self.masks[idx].stem
if image_name != mask_name:
raise FileNotFoundError(f"Annotation for file {image_name} is missing")
def __getitem__(self, index: int) -> Tuple[torch.Tensor, dict, str]:
"""Get one item from dataset
Args:
index (int): Item to get
Returns:
Tuple[torch.Tensor, dict, str]: Trainings-Batch
* torch.Tensor: Image
* dict: Ground-Truth values: keys are "instance map", "nuclei_binary_map" and "hv_map"
* str: filename
"""
img_path = self.images[index]
img = np.array(Image.open(img_path)).astype(np.uint8)
mask_path = self.masks[index]
mask = np.load(mask_path, allow_pickle=True)
inst_map = mask[()]["inst_map"].astype(np.int32)
type_map = mask[()]["type_map"].astype(np.int32)
mask = np.stack([inst_map, type_map], axis=-1)
if self.transforms is not None:
transformed = self.transforms(image=img, mask=mask)
img = transformed["image"]
mask = transformed["mask"]
inst_map = mask[:, :, 0].copy()
type_map = mask[:, :, 1].copy()
np_map = mask[:, :, 0].copy()
np_map[np_map > 0] = 1
hv_map = PanNukeDataset.gen_instance_hv_map(inst_map)
# torch convert
img = torch.Tensor(img).type(torch.float32)
img = img.permute(2, 0, 1)
if torch.max(img) >= 5:
img = img / 255
masks = {
"instance_map": torch.Tensor(inst_map).type(torch.int64),
"nuclei_type_map": torch.Tensor(type_map).type(torch.int64),
"nuclei_binary_map": torch.Tensor(np_map).type(torch.int64),
"hv_map": torch.Tensor(hv_map).type(torch.float32),
}
return img, masks, Path(img_path).name
def __len__(self) -> int:
"""Length of Dataset
Returns:
int: Length of Dataset
"""
return len(self.images)
def set_transforms(self, transforms: Callable) -> None:
"""Set the transformations, can be used tp exchange transformations
Args:
transforms (Callable): PyTorch transformations
"""
self.transforms = transforms