Skip to content

Commit 2ca781c

Browse files
committed
integrate volume sampler to semantic dataset
1 parent 2974070 commit 2ca781c

File tree

4 files changed

+55
-222
lines changed

4 files changed

+55
-222
lines changed

examples/mito.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
system:
2+
cpus: 1
3+
gpus: 1
4+
seed: 1
5+
6+
dataset:
7+
training:
8+
susumu100:
9+
images: ["file:///mnt/ceph/users/jwu/31_organelle/30_SM-WT1/84_susumu_inference/04_precomputed/image:mip=1",]
10+
label: "file:///mnt/ceph/users/jwu/31_organelle/30_SM-WT1/84_susumu_inference/04_precomputed/mito:mip=1"
11+
validation:
12+
susumu100:
13+
images: ["file:///mnt/ceph/users/jwu/31_organelle/30_SM-WT1/84_susumu_inference/04_precomputed/image:mip=1",]
14+
label: "file:///mnt/ceph/users/jwu/31_organelle/30_SM-WT1/84_susumu_inference/04_precomputed/mito:mip=1"
15+
model:
16+
in_channels: 1
17+
out_channels: 3
18+
19+
train:
20+
iter_start: 0
21+
iter_stop: 1000000
22+
class_rebalance: false
23+
# batch size per GPU
24+
# The dataprovider should provide nGPU*batch_size batches!
25+
batch_size: 1
26+
output_dir: "./"
27+
patch_size: [128, 128, 128]
28+
learning_rate: 0.001
29+
#training_interval: 200
30+
#validation_interval: 2000
31+
training_interval: 2
32+
validation_interval: 4

neutorch/data/dataset.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,16 @@ def __init__(self, samples: list):
123123
super().__init__(samples)
124124

125125
@classmethod
126-
def from_config(cls, cfg: CfgNode, is_train: bool):
126+
def from_config(cls, cfg: CfgNode, is_train: bool, **kwargs):
127+
"""Construct a semantic dataset with chunk or volume
128+
129+
Args:
130+
cfg (CfgNode): _description_
131+
is_train (bool): _description_
132+
133+
Returns:
134+
_type_: _description_
135+
"""
127136
if is_train:
128137
name2chunks = cfg.dataset.training
129138
else:
@@ -134,7 +143,8 @@ def from_config(cls, cfg: CfgNode, is_train: bool):
134143
sample = SemanticSample.from_explicit_dict(
135144
name2path,
136145
output_patch_size=cfg.train.patch_size,
137-
num_classes=cfg.model.out_channels)
146+
num_classes=cfg.model.out_channels,
147+
**kwargs)
138148
samples.append(sample)
139149

140150
return cls( samples )

neutorch/data/sample.py

Lines changed: 11 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55

66
import numpy as np
77

8-
from chunkflow.lib.cartesian_coordinate import BoundingBox, Cartesian, BoundingBoxes
9-
from chunkflow.chunk import Chunk, load_chunk
8+
from chunkflow.lib.cartesian_coordinate import BoundingBox, Cartesian
9+
from chunkflow.chunk import Chunk
10+
from chunkflow.chunk.utils import load_chunk_or_volume
1011
from chunkflow.lib.synapses import Synapses
1112

1213
from neutorch.data.patch import Patch
1314
from neutorch.data.transform import *
14-
15-
from cloudvolume import CloudVolume
15+
from chunkflow.volume import PrecomputedVolume
1616

1717
DEFAULT_PATCH_SIZE = Cartesian(128, 128, 128)
1818
DEFAULT_NUM_CLASSES = 1
@@ -48,7 +48,8 @@ def sampling_weight(self) -> int:
4848

4949
class Sample(AbstractSample):
5050
def __init__(self,
51-
images: List[Chunk], label: Union[np.ndarray, Chunk],
51+
images: List[Chunk, PrecomputedVolume],
52+
label: Union[Chunk, PrecomputedVolume],
5253
output_patch_size: Cartesian,
5354
forbbiden_distance_to_boundary: tuple = None) -> None:
5455
"""Image sample with ground truth annotations
@@ -351,13 +352,15 @@ def __init__(self,
351352
def from_explicit_path(cls,
352353
image_paths: list, label_path: str,
353354
output_patch_size: Cartesian,
354-
num_classes: int=DEFAULT_NUM_CLASSES):
355-
label = load_chunk(label_path)
355+
num_classes: int=DEFAULT_NUM_CLASSES,
356+
**kwargs,
357+
):
358+
label = load_chunk_or_volume(label_path, **kwargs)
356359
print(f'label path: {label_path} with size {label.shape}')
357360

358361
images = []
359362
for image_path in image_paths:
360-
image = load_chunk(image_path)
363+
image = load_chunk_or_volume(image_path, **kwargs)
361364
images.append(image)
362365
print(f'image path: {image_path} with size {image.shape}')
363366
return cls(images, label, output_patch_size, num_classes=num_classes)
@@ -438,76 +441,6 @@ def transform(self):
438441
# MissAlignment(),
439442
])
440443

441-
class PrecomputedVolumeSample(AbstractSample):
442-
def __init__(self,
443-
output_patch_size: Union[int, tuple, Cartesian],
444-
volume: Union[str, CloudVolume],
445-
mask: Chunk = None,
446-
forground_weight: int = None):
447-
"""Neuroglancer Precomputed Volume Dataset
448-
449-
Args:
450-
volume_path (str): cloudvolume precomputed path
451-
patch_size (Union[int, tuple], optional): patch size of network input. Defaults to volume block size.
452-
mask (Chunk, optional): forground mask. Defaults to None.
453-
forground_weight (int, optional): weight of bounding boxes containing forground voxels. Defaults to None.
454-
"""
455-
super.__init__(output_patch_size)
456-
457-
if isinstance(volume, str):
458-
self.vol = CloudVolume(
459-
volume,
460-
fill_missing=True,
461-
parallel=False,
462-
progress=False,
463-
green_threads = False,
464-
)
465-
elif isinstance(volume, CloudVolume):
466-
self.vol = volume
467-
else:
468-
raise ValueError("volume should be either an instance of CloudVolume or precomputed volume path.")
469-
470-
# self.voxel_size = tuple(self.vol.resolution)
471-
472-
self.bboxes = BoundingBoxes.from_manual_setup(
473-
self.output_patch_size,
474-
roi_start=(0, 0, 0),
475-
roi_stop=self.vol.bounds.maxpt[-3:][::-1],
476-
bounded=True,
477-
)
478-
print(f'found {len(self.bboxes)} bounding boxes in volume: {volume}')
479-
480-
if mask is not None:
481-
# find out bboxes containing forground voxels
482-
483-
if forground_weight is None:
484-
pass
485-
486-
def __getitem__(self, idx: int):
487-
bbox = self.bboxes[idx]
488-
xyz_slices = bbox.to_slices()[::-1]
489-
print('xyz slices: ', xyz_slices)
490-
image = self.vol[xyz_slices]
491-
image = np.asarray(image)
492-
image = np.transpose(image)
493-
# image = image.astype(np.float32)
494-
# image /= 255.
495-
# chunk = Chunk(arr, voxel_offset=bbox.minpt, voxel_size=self.voxel_size)
496-
# tensor = torch.Tensor(arr)
497-
target = deepcopy(image)
498-
patch = Patch(image, target)
499-
self.transform(patch)
500-
patch.to_tensor()
501-
patch.normalize()
502-
return patch.image, patch.target
503-
504-
@property
505-
def random_patch(self):
506-
idx = random.randrange(0, len(self.bboxes))
507-
return self.__getitem__(idx)
508-
509-
def __len__(self):
510-
return len(self.bboxes)
511444

512445
if __name__ == '__main__':
513446
import os

neutorch/data/volume.py

Lines changed: 0 additions & 142 deletions
This file was deleted.

0 commit comments

Comments
 (0)