File size: 4,841 Bytes
ecf08bc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# Copyright 2020 Division of Medical Image Computing, German Cancer Research Center (DKFZ), Heidelberg, Germany
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import numpy as np
from batchgenerators.transforms.abstract_transforms import AbstractTransform
class RemoveKeyTransform(AbstractTransform):
def __init__(self, key_to_remove):
self.key_to_remove = key_to_remove
def __call__(self, **data_dict):
_ = data_dict.pop(self.key_to_remove, None)
return data_dict
class MaskTransform(AbstractTransform):
def __init__(self, dct_for_where_it_was_used, mask_idx_in_seg=1, set_outside_to=0, data_key="data", seg_key="seg"):
"""
data[mask < 0] = 0
Sets everything outside the mask to 0. CAREFUL! outside is defined as < 0, not =0 (in the Mask)!!!
:param dct_for_where_it_was_used:
:param mask_idx_in_seg:
:param set_outside_to:
:param data_key:
:param seg_key:
"""
self.dct_for_where_it_was_used = dct_for_where_it_was_used
self.seg_key = seg_key
self.data_key = data_key
self.set_outside_to = set_outside_to
self.mask_idx_in_seg = mask_idx_in_seg
def __call__(self, **data_dict):
seg = data_dict.get(self.seg_key)
if seg is None or seg.shape[1] < self.mask_idx_in_seg:
raise Warning("mask not found, seg may be missing or seg[:, mask_idx_in_seg] may not exist")
data = data_dict.get(self.data_key)
for b in range(data.shape[0]):
mask = seg[b, self.mask_idx_in_seg]
for c in range(data.shape[1]):
if self.dct_for_where_it_was_used[c]:
data[b, c][mask < 0] = self.set_outside_to
data_dict[self.data_key] = data
return data_dict
def convert_3d_to_2d_generator(data_dict):
shp = data_dict['data'].shape
data_dict['data'] = data_dict['data'].reshape((shp[0], shp[1] * shp[2], shp[3], shp[4]))
data_dict['orig_shape_data'] = shp
shp = data_dict['seg'].shape
data_dict['seg'] = data_dict['seg'].reshape((shp[0], shp[1] * shp[2], shp[3], shp[4]))
data_dict['orig_shape_seg'] = shp
return data_dict
def convert_2d_to_3d_generator(data_dict):
shp = data_dict['orig_shape_data']
current_shape = data_dict['data'].shape
data_dict['data'] = data_dict['data'].reshape((shp[0], shp[1], shp[2], current_shape[-2], current_shape[-1]))
shp = data_dict['orig_shape_seg']
current_shape_seg = data_dict['seg'].shape
data_dict['seg'] = data_dict['seg'].reshape((shp[0], shp[1], shp[2], current_shape_seg[-2], current_shape_seg[-1]))
return data_dict
class Convert3DTo2DTransform(AbstractTransform):
def __init__(self):
pass
def __call__(self, **data_dict):
return convert_3d_to_2d_generator(data_dict)
class Convert2DTo3DTransform(AbstractTransform):
def __init__(self):
pass
def __call__(self, **data_dict):
return convert_2d_to_3d_generator(data_dict)
class ConvertSegmentationToRegionsTransform(AbstractTransform):
def __init__(self, regions: dict, seg_key: str = "seg", output_key: str = "seg", seg_channel: int = 0):
"""
regions are tuple of tuples where each inner tuple holds the class indices that are merged into one region, example:
regions= ((1, 2), (2, )) will result in 2 regions: one covering the region of labels 1&2 and the other just 2
:param regions:
:param seg_key:
:param output_key:
"""
self.seg_channel = seg_channel
self.output_key = output_key
self.seg_key = seg_key
self.regions = regions
def __call__(self, **data_dict):
seg = data_dict.get(self.seg_key)
num_regions = len(self.regions)
if seg is not None:
seg_shp = seg.shape
output_shape = list(seg_shp)
output_shape[1] = num_regions
region_output = np.zeros(output_shape, dtype=seg.dtype)
for b in range(seg_shp[0]):
for r, k in enumerate(self.regions.keys()):
for l in self.regions[k]:
region_output[b, r][seg[b, self.seg_channel] == l] = 1
data_dict[self.output_key] = region_output
return data_dict
|