torch_em.data.datasets.electron_microscopy.deepcontact
DeepContact dataset for organelle segmentation in 2D EM.
The dataset contains 2D SEM and TEM images of cultured cells and tissue with manual polygon annotations for three organelle classes:
- mito: mitochondria
- er: endoplasmic reticulum
- ld: lipid droplets
Data is provided as LabelMe JSON annotations paired with TIFF images. During preprocessing, polygon annotations are rasterized to binary label masks and stored alongside the raw images in HDF5 files.
Three image sources are available:
- cell: SEM images of U-2 OS cultured cells at 5 nm/px
- sem: SEM images of Sertoli tissue cells at 10 nm/px
- tem: TEM images at 4.68 nm/px
This dataset is from the publication https://doi.org/10.1083/jcb.202106190. Please cite it if you use this dataset in your research.
The data is available at https://figshare.com/articles/dataset/DeepContact_Training_Data/19898404.
1"""DeepContact dataset for organelle segmentation in 2D EM. 2 3The dataset contains 2D SEM and TEM images of cultured cells and tissue with 4manual polygon annotations for three organelle classes: 5- mito: mitochondria 6- er: endoplasmic reticulum 7- ld: lipid droplets 8 9Data is provided as LabelMe JSON annotations paired with TIFF images. 10During preprocessing, polygon annotations are rasterized to binary label masks 11and stored alongside the raw images in HDF5 files. 12 13Three image sources are available: 14- cell: SEM images of U-2 OS cultured cells at 5 nm/px 15- sem: SEM images of Sertoli tissue cells at 10 nm/px 16- tem: TEM images at 4.68 nm/px 17 18This dataset is from the publication https://doi.org/10.1083/jcb.202106190. 19Please cite it if you use this dataset in your research. 20 21The data is available at https://figshare.com/articles/dataset/DeepContact_Training_Data/19898404. 22""" 23 24import os 25from glob import glob 26from typing import List, Literal, Optional, Tuple, Union 27 28import numpy as np 29from tqdm import tqdm 30 31import torch_em 32from torch.utils.data import Dataset, DataLoader 33from .. import util 34 35 36DEEPCONTACT_URLS = { 37 "cell": ("https://ndownloader.figshare.com/files/35317564", "cell_data.zip"), 38 "sem": ("https://ndownloader.figshare.com/files/35317573", "sem_data.zip"), 39 "tem": ("https://ndownloader.figshare.com/files/35317576", "tem_data.zip"), 40} 41 42DEEPCONTACT_CHECKSUMS = { 43 "cell": None, 44 "sem": None, 45 "tem": None, 46} 47 48DEEPCONTACT_LABEL_NAMES = { 49 "mito": ["Mito", "mito", "Mitochondria", "mitochondria"], 50 "er": ["ER", "er"], 51 "ld": ["Lipid Droplets", "lipid droplets", "LipidDroplets", "LD", "ld"], 52} 53 54 55def _rasterize_labelme_json(json_path, label_choice): 56 import json 57 from skimage.draw import polygon as sk_polygon 58 59 with open(json_path) as f: 60 data = json.load(f) 61 62 h = data.get("imageHeight") or data.get("image_height") 63 w = data.get("imageWidth") or data.get("image_width") 64 mask = np.zeros((h, w), dtype=np.uint8) 65 66 target_names = DEEPCONTACT_LABEL_NAMES[label_choice] 67 for shape in data.get("shapes", []): 68 if shape.get("label") not in target_names: 69 continue 70 pts = np.array(shape["points"]) 71 rr, cc = sk_polygon(pts[:, 1], pts[:, 0], shape=(h, w)) 72 mask[rr, cc] = 1 73 74 return mask 75 76 77def _find_image_for_json(json_path): 78 from imageio import imread 79 80 base = os.path.splitext(json_path)[0] 81 for ext in [".tif", ".tiff", ".png", ".jpg", ".jpeg"]: 82 img_path = base + ext 83 if os.path.exists(img_path): 84 return imread(img_path) 85 86 # Check imagePath field in JSON 87 import json 88 with open(json_path) as f: 89 data = json.load(f) 90 img_name = data.get("imagePath", "") 91 img_path = os.path.join(os.path.dirname(json_path), img_name) 92 if os.path.exists(img_path): 93 return imread(img_path) 94 95 return None 96 97 98def _preprocess_source(extract_dir, output_dir, source): 99 from elf.io import open_file 100 101 os.makedirs(output_dir, exist_ok=True) 102 json_files = sorted(glob(os.path.join(extract_dir, "**", "*.json"), recursive=True)) 103 104 for json_path in tqdm(json_files, desc=f"Processing {source}"): 105 name = os.path.splitext(os.path.relpath(json_path, extract_dir))[0].replace(os.sep, "_") 106 h5_path = os.path.join(output_dir, f"{name}.h5") 107 if os.path.exists(h5_path): 108 continue 109 110 raw = _find_image_for_json(json_path) 111 if raw is None: 112 continue 113 114 if raw.ndim == 3: 115 raw = raw[..., 0] 116 117 with open_file(h5_path, "a") as f: 118 f.create_dataset("raw", data=raw.astype(np.uint8), compression="gzip") 119 for label_choice in DEEPCONTACT_LABEL_NAMES: 120 mask = _rasterize_labelme_json(json_path, label_choice) 121 f.create_dataset(f"labels/{label_choice}", data=mask, compression="gzip") 122 123 124def get_deepcontact_data( 125 path: Union[os.PathLike, str], 126 sources: Optional[List[Literal["cell", "sem", "tem"]]] = None, 127 download: bool = False, 128) -> str: 129 """Download and preprocess the DeepContact dataset. 130 131 Args: 132 path: Filepath to a folder where the data will be saved. 133 sources: Which image sources to use. Defaults to all ("cell", "sem", "tem"). 134 download: Whether to download the data if not present. 135 136 Returns: 137 Path to the folder containing preprocessed HDF5 files. 138 """ 139 if sources is None: 140 sources = ["cell", "sem", "tem"] 141 142 processed_dir = os.path.join(str(path), "processed") 143 os.makedirs(str(path), exist_ok=True) 144 145 for source in sources: 146 source_dir = os.path.join(processed_dir, source) 147 if os.path.isdir(source_dir) and len(glob(os.path.join(source_dir, "*.h5"))) > 0: 148 continue 149 150 url, fname = DEEPCONTACT_URLS[source] 151 zip_path = os.path.join(str(path), fname) 152 153 if not os.path.exists(zip_path): 154 if not download: 155 raise RuntimeError( 156 f"Data for source '{source}' not found at '{zip_path}'. " 157 "Set download=True or download manually from " 158 "https://figshare.com/articles/dataset/DeepContact_Training_Data/19898404." 159 ) 160 util.download_source(zip_path, url, download, checksum=DEEPCONTACT_CHECKSUMS[source]) 161 162 extract_dir = os.path.join(str(path), f"{source}_raw") 163 if not os.path.isdir(extract_dir): 164 util.unzip(zip_path, extract_dir, remove=False) 165 166 _preprocess_source(extract_dir, source_dir, source) 167 168 return processed_dir 169 170 171def get_deepcontact_paths( 172 path: Union[os.PathLike, str], 173 sources: Optional[List[Literal["cell", "sem", "tem"]]] = None, 174 download: bool = False, 175) -> List[str]: 176 """Get paths to DeepContact HDF5 files. 177 178 Args: 179 path: Filepath to a folder where the data will be saved. 180 sources: Which image sources to use. Defaults to all ("cell", "sem", "tem"). 181 download: Whether to download the data if not present. 182 183 Returns: 184 List of paths to HDF5 files. 185 """ 186 if sources is None: 187 sources = ["cell", "sem", "tem"] 188 processed_dir = get_deepcontact_data(path, sources, download) 189 paths = [] 190 for source in sources: 191 paths.extend(sorted(glob(os.path.join(processed_dir, source, "*.h5")))) 192 return paths 193 194 195def get_deepcontact_dataset( 196 path: Union[os.PathLike, str], 197 patch_shape: Tuple[int, int], 198 label_choice: Literal["mito", "er", "ld"] = "mito", 199 sources: Optional[List[Literal["cell", "sem", "tem"]]] = None, 200 download: bool = False, 201 **kwargs, 202) -> Dataset: 203 """Get the DeepContact dataset for organelle segmentation in 2D EM. 204 205 Args: 206 path: Filepath to a folder where the data will be saved. 207 patch_shape: The patch shape (H, W) for training. 208 label_choice: Which organelle to segment. One of "mito", "er", or "ld". 209 sources: Which image sources to use. Defaults to all ("cell", "sem", "tem"). 210 download: Whether to download the data if not present. 211 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 212 213 Returns: 214 The segmentation dataset. 215 """ 216 assert len(patch_shape) == 2 217 data_paths = get_deepcontact_paths(path, sources, download) 218 219 return torch_em.default_segmentation_dataset( 220 raw_paths=data_paths, 221 raw_key="raw", 222 label_paths=data_paths, 223 label_key=f"labels/{label_choice}", 224 patch_shape=patch_shape, 225 **kwargs, 226 ) 227 228 229def get_deepcontact_loader( 230 path: Union[os.PathLike, str], 231 batch_size: int, 232 patch_shape: Tuple[int, int], 233 label_choice: Literal["mito", "er", "ld"] = "mito", 234 sources: Optional[List[Literal["cell", "sem", "tem"]]] = None, 235 download: bool = False, 236 **kwargs, 237) -> DataLoader: 238 """Get the DataLoader for organelle segmentation in the DeepContact dataset. 239 240 Args: 241 path: Filepath to a folder where the data will be saved. 242 batch_size: The batch size for training. 243 patch_shape: The patch shape (H, W) for training. 244 label_choice: Which organelle to segment. One of "mito", "er", or "ld". 245 sources: Which image sources to use. Defaults to all ("cell", "sem", "tem"). 246 download: Whether to download the data if not present. 247 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` 248 or for the PyTorch DataLoader. 249 250 Returns: 251 The DataLoader. 252 """ 253 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 254 ds = get_deepcontact_dataset( 255 path=path, 256 patch_shape=patch_shape, 257 label_choice=label_choice, 258 sources=sources, 259 download=download, 260 **ds_kwargs, 261 ) 262 return torch_em.get_data_loader(ds, batch_size=batch_size, **loader_kwargs)
125def get_deepcontact_data( 126 path: Union[os.PathLike, str], 127 sources: Optional[List[Literal["cell", "sem", "tem"]]] = None, 128 download: bool = False, 129) -> str: 130 """Download and preprocess the DeepContact dataset. 131 132 Args: 133 path: Filepath to a folder where the data will be saved. 134 sources: Which image sources to use. Defaults to all ("cell", "sem", "tem"). 135 download: Whether to download the data if not present. 136 137 Returns: 138 Path to the folder containing preprocessed HDF5 files. 139 """ 140 if sources is None: 141 sources = ["cell", "sem", "tem"] 142 143 processed_dir = os.path.join(str(path), "processed") 144 os.makedirs(str(path), exist_ok=True) 145 146 for source in sources: 147 source_dir = os.path.join(processed_dir, source) 148 if os.path.isdir(source_dir) and len(glob(os.path.join(source_dir, "*.h5"))) > 0: 149 continue 150 151 url, fname = DEEPCONTACT_URLS[source] 152 zip_path = os.path.join(str(path), fname) 153 154 if not os.path.exists(zip_path): 155 if not download: 156 raise RuntimeError( 157 f"Data for source '{source}' not found at '{zip_path}'. " 158 "Set download=True or download manually from " 159 "https://figshare.com/articles/dataset/DeepContact_Training_Data/19898404." 160 ) 161 util.download_source(zip_path, url, download, checksum=DEEPCONTACT_CHECKSUMS[source]) 162 163 extract_dir = os.path.join(str(path), f"{source}_raw") 164 if not os.path.isdir(extract_dir): 165 util.unzip(zip_path, extract_dir, remove=False) 166 167 _preprocess_source(extract_dir, source_dir, source) 168 169 return processed_dir
Download and preprocess the DeepContact dataset.
Arguments:
- path: Filepath to a folder where the data will be saved.
- sources: Which image sources to use. Defaults to all ("cell", "sem", "tem").
- download: Whether to download the data if not present.
Returns:
Path to the folder containing preprocessed HDF5 files.
172def get_deepcontact_paths( 173 path: Union[os.PathLike, str], 174 sources: Optional[List[Literal["cell", "sem", "tem"]]] = None, 175 download: bool = False, 176) -> List[str]: 177 """Get paths to DeepContact HDF5 files. 178 179 Args: 180 path: Filepath to a folder where the data will be saved. 181 sources: Which image sources to use. Defaults to all ("cell", "sem", "tem"). 182 download: Whether to download the data if not present. 183 184 Returns: 185 List of paths to HDF5 files. 186 """ 187 if sources is None: 188 sources = ["cell", "sem", "tem"] 189 processed_dir = get_deepcontact_data(path, sources, download) 190 paths = [] 191 for source in sources: 192 paths.extend(sorted(glob(os.path.join(processed_dir, source, "*.h5")))) 193 return paths
Get paths to DeepContact HDF5 files.
Arguments:
- path: Filepath to a folder where the data will be saved.
- sources: Which image sources to use. Defaults to all ("cell", "sem", "tem").
- download: Whether to download the data if not present.
Returns:
List of paths to HDF5 files.
196def get_deepcontact_dataset( 197 path: Union[os.PathLike, str], 198 patch_shape: Tuple[int, int], 199 label_choice: Literal["mito", "er", "ld"] = "mito", 200 sources: Optional[List[Literal["cell", "sem", "tem"]]] = None, 201 download: bool = False, 202 **kwargs, 203) -> Dataset: 204 """Get the DeepContact dataset for organelle segmentation in 2D EM. 205 206 Args: 207 path: Filepath to a folder where the data will be saved. 208 patch_shape: The patch shape (H, W) for training. 209 label_choice: Which organelle to segment. One of "mito", "er", or "ld". 210 sources: Which image sources to use. Defaults to all ("cell", "sem", "tem"). 211 download: Whether to download the data if not present. 212 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 213 214 Returns: 215 The segmentation dataset. 216 """ 217 assert len(patch_shape) == 2 218 data_paths = get_deepcontact_paths(path, sources, download) 219 220 return torch_em.default_segmentation_dataset( 221 raw_paths=data_paths, 222 raw_key="raw", 223 label_paths=data_paths, 224 label_key=f"labels/{label_choice}", 225 patch_shape=patch_shape, 226 **kwargs, 227 )
Get the DeepContact dataset for organelle segmentation in 2D EM.
Arguments:
- path: Filepath to a folder where the data will be saved.
- patch_shape: The patch shape (H, W) for training.
- label_choice: Which organelle to segment. One of "mito", "er", or "ld".
- sources: Which image sources to use. Defaults to all ("cell", "sem", "tem").
- download: Whether to download the data if not present.
- kwargs: Additional keyword arguments for
torch_em.default_segmentation_dataset.
Returns:
The segmentation dataset.
230def get_deepcontact_loader( 231 path: Union[os.PathLike, str], 232 batch_size: int, 233 patch_shape: Tuple[int, int], 234 label_choice: Literal["mito", "er", "ld"] = "mito", 235 sources: Optional[List[Literal["cell", "sem", "tem"]]] = None, 236 download: bool = False, 237 **kwargs, 238) -> DataLoader: 239 """Get the DataLoader for organelle segmentation in the DeepContact dataset. 240 241 Args: 242 path: Filepath to a folder where the data will be saved. 243 batch_size: The batch size for training. 244 patch_shape: The patch shape (H, W) for training. 245 label_choice: Which organelle to segment. One of "mito", "er", or "ld". 246 sources: Which image sources to use. Defaults to all ("cell", "sem", "tem"). 247 download: Whether to download the data if not present. 248 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` 249 or for the PyTorch DataLoader. 250 251 Returns: 252 The DataLoader. 253 """ 254 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 255 ds = get_deepcontact_dataset( 256 path=path, 257 patch_shape=patch_shape, 258 label_choice=label_choice, 259 sources=sources, 260 download=download, 261 **ds_kwargs, 262 ) 263 return torch_em.get_data_loader(ds, batch_size=batch_size, **loader_kwargs)
Get the DataLoader for organelle segmentation in the DeepContact dataset.
Arguments:
- path: Filepath to a folder where the data will be saved.
- batch_size: The batch size for training.
- patch_shape: The patch shape (H, W) for training.
- label_choice: Which organelle to segment. One of "mito", "er", or "ld".
- sources: Which image sources to use. Defaults to all ("cell", "sem", "tem").
- download: Whether to download the data if not present.
- kwargs: Additional keyword arguments for
torch_em.default_segmentation_datasetor for the PyTorch DataLoader.
Returns:
The DataLoader.