def setUp(self): self.folder_in = tempfile.mkdtemp() for i in range(10): DicommlCase(**sample_case_config( caseid='train-case-{i}'.format(i=i), n_images=10)).save( os.path.join(self.folder_in, 'train')) for i in range(4): DicommlCase(**sample_case_config( caseid='eval-case-{i}'.format(i=i), n_images=10)).save( os.path.join(self.folder_in, 'eval'))
def __call__(self, files: List[str] = []) -> List[DicommlCase]: if self.load_from_dicom: cases = [ DicommlCase.from_dicom_zipfile(_file, **self.load_config) for _file in files ] else: cases = [DicommlCase.load(_file) for _file in files] self.logger.info('Loaded cases: {}'.format( [case.caseid for case in cases])) return cases
class TestExpandTransforms(unittest.TestCase): def test_split(self): case = DicommlCase(**sample_case_config(n_images=10)) cases_new = expand.Split(n_images=2)([case]) self.assertEqual(len(cases_new), 5) for case in cases_new: self.assertIsInstance(case, DicommlCase)
class ArrayTransform(DicommlTransform): """ Basic image transforms """ def __init__(self, apply_to_image: bool = True, apply_to_roi: bool = True, **kwargs): super(ArrayTransform, self).__init__(**kwargs) self.apply_to_image = apply_to_image self.apply_to_roi = apply_to_roi def transform_case(self, case: DicommlCase) -> DicommlCase: if self.apply_to_image: images = { key: self._transform_array(arr) for key, arr in case.images.items() } else: images = case.images if self.apply_to_roi: rois = { key: self._transform_array(arr) for key, arr in case.rois.items() } else: rois = case.rois self.logger.debug('Applied transform to case {}'.format(case.caseid)) return DicommlCase(caseid=case.caseid, images=images, images_metadata=case.images_metadata, rois=rois, diagnose=case.diagnose, images_to_diagnosis=case.images_to_diagnosis, images_to_rois=case.images_to_rois)
class AddPredictions(DicommlTransform): """ Adds model predictions to a case """ def __init__(self, model: tf.keras.Model, model_predicts_labels: bool = False, model_predicts_rois: bool = False, order_images_with_index: bool = True, diagnose_label_set: List[str] = [], label_threshold: float = 0.5, **kwargs): super(AddPredictions, self).__init__(**kwargs) self.model = model self.model_predicts_labels = model_predicts_labels self.model_predicts_rois = model_predicts_rois self.order_images_with_index = order_images_with_index self.diagnose_label_set = diagnose_label_set self.label_threshold = label_threshold def transform_case(self, case: DicommlCase) -> DicommlCase: images = case.export( order_images_with_index=self.order_images_with_index)['images'] labels, rois = self._model_predictions(images) if self.order_images_with_index: image_keys = sorted(case.images.keys()) else: image_keys = case.images.keys() labels_names = { str(i): diagnose for i, diagnose in enumerate(self.diagnose_label_set) } case_images_to_labels = {} case_rois = {} case_images_to_rois = {} for i, imgkey in enumerate(image_keys): if rois is not None: case_rois.update({str(i): rois[i, ...]}) case_images_to_rois.update({imgkey: [str(i)]}) if labels is not None: _logits = labels[i, ...].tolist() _labels = [ j for j, _ in enumerate(self.diagnose_label_set) if _logits[j] >= self.label_threshold ] case_images_to_labels.update({imgkey: _labels}) return DicommlCase(caseid=case.caseid, images=case.images, images_metadata=case.images_metadata, rois=rois, diagnose=labels_names, images_to_diagnosis=case_images_to_labels, images_to_rois=case_images_to_rois)
def load(self, idx): return [DicommlCase.load(self.files[idx])]
class TestArrayTransforms(unittest.TestCase): def test_shift(self): case = DicommlCase(**sample_case_config()) case_new = transforms.Shift(x_shift=2, y_shift=34)([case])[0] self.assertEqual(case.export()['images'].shape, case_new.export()['images'].shape)
from dicomml.cases.case import DicommlCase from dicomml.transforms import array as transforms from dicomml.transforms import expand from tests import sample_case_config class TestArrayTransforms(unittest.TestCase): def test_shift(self): case = DicommlCase(**sample_case_config()) case_new = transforms.Shift(x_shift=2, y_shift=34)([case])[0] self.assertEqual(case.export()['images'].shape, case_new.export()['images'].shape) def test_mirror(self): case = DicommlCase(**sample_case_config()) case_new = transforms.Mirror()([case])[0] self.assertEqual(case.export()['images'].shape, case_new.export()['images'].shape) def test_cut(self): case = DicommlCase(**sample_case_config()) case_new = transforms.Cut(x_range=[30, 90], y_range=[20, 100])([case])[0] self.assertEqual((1, case.export()['images'].shape[1], 60, 80), case_new.export()['images'].shape) def test_pad(self): case = DicommlCase(**sample_case_config()) case_new = transforms.Pad(target_shape=[200, 150])([case])[0] self.assertEqual((1, case.export()['images'].shape[1], 200, 150),
arrs = [] for i, (index, arr) in enumerate(sorted(case.images.items())): if len(arr.shape) == 2: arr = arr[..., np.newaxis] arrs.append(arr) index_to_arr_i.update({index: i}) imgarrays = np.array_split( np.stack(arrs, axis=0), indices_or_sections=self.n_images_batch, axis=0) _out = [] for imgarray in imgarrays: _out.append(self._apply_cnn(imgarray)) transformed_array = np.concatenate(_out, axis=0) # turn into dictionary again return DicommlCase( caseid=case.caseid, images={ index: transformed_array[i, ...] for index, i in index_to_arr_i.items()}, images_metadata=case.images_metadata, rois=case.rois, diagnose=case.diagnose, images_to_diagnosis=case.images_to_diagnosis, images_to_rois=case.images_to_rois) def _apply_cnn(self, arr): if self.normalize_images: arr = tf.cast(arr, dtype=tf.float32) arr = tf.convert_to_tensor(arr, dtype=tf.float32) / 127.5 arr -= 1. arr = tf.tile(arr, [1, 1, 1, 3])
if img in case.images_to_rois.keys(): roi_keys_for_image = case.images_to_rois[img] images_to_rois.update({img: roi_keys_for_image}) rois.update({ key: val for key, val in case.rois.items() if key in roi_keys_for_image}) case_configs.append(dict( caseid=caseid, images=images, images_metadata=images_metadata, rois=rois, diagnose=diagnose, images_to_diagnosis=images_to_diagnosis, images_to_rois=images_to_rois)) return [DicommlCase(**cfg) for cfg in case_configs] class AddTranforms(DicommlTransform): def __init__(self, base_transform: Union[Type[ArrayTransform], str], base_config: dict = dict(), value_ranges: Dict[str, tuple] = dict(), n_applications: int = 1, **kwargs): if isinstance(base_transform, str): Transform = dicomml_resolve(base_transform) else: Transform = base_transform transform_configs = []
class TestDicommlCase(unittest.TestCase): def test_create(self): case = DicommlCase(**sample_case_config()) self.assertIsInstance(case, DicommlCase)
import unittest import tempfile from dicomml.cases.case import DicommlCase from tests import sample_case_config class TestDicommlCase(unittest.TestCase): def test_create(self): case = DicommlCase(**sample_case_config()) self.assertIsInstance(case, DicommlCase) def test_save_load(self): case = DicommlCase(**sample_case_config()) with tempfile.TemporaryDirectory() as temp_folder: zipfile = case.save(path=temp_folder) case_loaded = DicommlCase.load(zipfile) self.assertEqual(case, case_loaded) def test_export(self): case = DicommlCase(**sample_case_config()) exports = case.export() self.assertCountEqual( list(exports.keys()), ['images', 'truth']) self.assertEqual(exports['images'].shape, (1, 10, 120, 120))
def setUp(self): self.folder_in = tempfile.mkdtemp() self.folder_out = tempfile.mkdtemp() for i in range(4): DicommlCase(**sample_case_config(caseid='case-{i}'.format(i=i), n_images=10)).save(self.folder_in)