def test_save_segmentation_without_image(self, tmpdir, data_test_dir): seg = LoadROIImage.load( [os.path.join(data_test_dir, "test_nucleus_1_1.seg")], metadata={"default_spacing": (1, 1, 1)} ) seg_clean = dataclasses.replace(seg, image=None, roi=reduce_array(seg.roi)) SaveROI.save(os.path.join(tmpdir, "segmentation.seg"), seg_clean, {"relative_path": False}) SaveROI.save( os.path.join(tmpdir, "segmentation1.seg"), seg_clean, {"relative_path": False, "spacing": (210 * 10 ** -6, 70 * 10 ** -6, 70 * 10 ** -6)}, )
def get_mask(segmentation: typing.Optional[np.ndarray], mask: typing.Optional[np.ndarray], selected: typing.List[int]): """ Calculate mask base on segmentation, current mask and list of chosen components. :param typing.Optional[np.ndarray] segmentation: segmentation array :param typing.Optional[np.ndarray] mask: current mask :param typing.List[int] selected: list of selected components :return: new mask :rtype: typing.Optional[np.ndarray] """ if segmentation is None or len(selected) == 0: return None if mask is None else mask segmentation = reduce_array(segmentation, selected) if mask is None: resp = np.ones(segmentation.shape, dtype=np.uint8) else: resp = np.copy(mask) resp[segmentation > 0] = 0 return resp
def transform_state( state: SegmentationTuple, new_segmentation_data: np.ndarray, segmentation_parameters: typing.Dict, list_of_components: typing.List[int], save_chosen: bool = True, ) -> SegmentationTuple: if list_of_components is None: list_of_components = [] if segmentation_parameters is None: segmentation_parameters = defaultdict(lambda: None) segmentation_count = 0 if state.segmentation is None else len( np.unique(state.segmentation.flat)) new_segmentation_count = 0 if new_segmentation_data is None else len( np.unique(new_segmentation_data.flat)) segmentation_dtype = minimal_dtype(segmentation_count + new_segmentation_count) if save_chosen and state.segmentation is not None: segmentation = reduce_array(state.segmentation, state.selected_components, dtype=segmentation_dtype) components_parameters_dict = {} for i, val in enumerate(sorted(state.selected_components), 1): components_parameters_dict[i] = state.segmentation_parameters[ val] base_chose = list(range(1, len(state.selected_components) + 1)) else: segmentation = None base_chose = [] components_parameters_dict = {} if new_segmentation_data is not None: state.image.fit_array_to_image(new_segmentation_data) num = np.max(new_segmentation_data) if segmentation is not None: new_segmentation = np.copy(new_segmentation_data) new_segmentation[segmentation > 0] = 0 new_segmentation = reduce_array(new_segmentation, dtype=segmentation_dtype) segmentation[new_segmentation > 0] = new_segmentation[ new_segmentation > 0] + len(base_chose) components_size = np.bincount(new_segmentation.flat) base_index = len(base_chose) + 1 chosen_components = base_chose[:] components_list = base_chose[:] for i, val in enumerate(components_size[1:], 1): if val > 0: if i in list_of_components: chosen_components.append(base_index) components_list.append(base_index) components_parameters_dict[ base_index] = segmentation_parameters[i] base_index += 1 return dataclasses.replace( state, segmentation=segmentation, selected_components=chosen_components, segmentation_parameters=components_parameters_dict, ) else: for i in range(1, num + 1): components_parameters_dict[i] = segmentation_parameters[i] return dataclasses.replace( state, segmentation=new_segmentation_data, selected_components=list_of_components, segmentation_parameters=components_parameters_dict, ) else: return dataclasses.replace( state, segmentation=segmentation, selected_components=base_chose, segmentation_parameters=components_parameters_dict, )
def load_stack_segmentation(file_data: typing.Union[str, Path], range_changed=None, step_changed=None): if range_changed is None: range_changed = empty_fun if step_changed is None: step_changed = empty_fun range_changed(0, 7) tar_file = open_tar_file(file_data)[0] try: if check_segmentation_type(tar_file) != SegmentationType.mask: raise WrongFileTypeException() files = tar_file.getnames() step_changed(1) metadata = load_metadata( tar_file.extractfile("metadata.json").read().decode("utf8")) step_changed(2) if "segmentation.npy" in files: segmentation_file_name = "segmentation.npy" segmentation_load_fun = np.load else: segmentation_file_name = "segmentation.tif" segmentation_load_fun = TiffImageReader.read_image segmentation_buff = BytesIO() segmentation_tar = tar_file.extractfile( tar_file.getmember(segmentation_file_name)) segmentation_buff.write(segmentation_tar.read()) step_changed(3) segmentation_buff.seek(0) segmentation = segmentation_load_fun(segmentation_buff) if isinstance(segmentation, Image): spacing = segmentation.spacing segmentation = segmentation.get_channel(0) else: spacing = None segmentation = reduce_array(segmentation) step_changed(4) if "mask.tif" in tar_file.getnames(): mask = tifffile.imread(tar_to_buff(tar_file, "mask.tif")) if np.max(mask) == 1: mask = mask.astype(np.bool) else: mask = None step_changed(5) history = [] try: history_buff = tar_file.extractfile( tar_file.getmember("history/history.json")).read() history_json = load_metadata(history_buff) for el in history_json: history_buffer = BytesIO() history_buffer.write( tar_file.extractfile( f"history/arrays_{el['index']}.npz").read()) history_buffer.seek(0) history.append( HistoryElement( segmentation_parameters=el["segmentation_parameters"], mask_property=el["mask_property"], arrays=history_buffer, )) except KeyError: pass step_changed(6) finally: if isinstance(file_data, (str, Path)): tar_file.close() return SegmentationTuple( file_path=file_data if isinstance(file_data, str) else "", image=metadata["base_file"] if "base_file" in metadata else None, segmentation=segmentation, selected_components=metadata["components"], mask=mask, segmentation_parameters=metadata["parameters"] if "parameters" in metadata else None, history=history, spacing=([10**-9] + list(spacing)) if spacing is not None else None, )
def transform_state( cls, state: MaskProjectTuple, new_roi_info: ROIInfo, new_roi_extraction_parameters: typing.Dict[ int, typing.Optional[ROIExtractionProfile]], list_of_components: typing.List[int], save_chosen: bool = True, ) -> MaskProjectTuple: """ :param MaskProjectTuple state: state to be transformed :param ROIInfo new_roi_info: roi description :param typing.Dict[int, typing.Optional[ROIExtractionProfile]] new_roi_extraction_parameters: Parameters used to extract roi :param typing.List[int] list_of_components: list of components from new_roi which should be selected :param bool save_chosen: if save currently selected components :return: new state """ # TODO Refactor if not save_chosen or state.roi_info.roi is None or len( state.selected_components) == 0: return dataclasses.replace( state, roi_info=new_roi_info, selected_components=list_of_components, roi_extraction_parameters={ i: new_roi_extraction_parameters[i] for i in new_roi_info.bound_info }, ) if list_of_components is None: list_of_components = [] if new_roi_extraction_parameters is None: new_roi_extraction_parameters = defaultdict(lambda: None) segmentation_count = len(state.roi_info.bound_info) new_segmentation_count = len(new_roi_info.bound_info) segmentation_dtype = minimal_dtype(segmentation_count + new_segmentation_count) roi_base = reduce_array(state.roi_info.roi, state.selected_components, dtype=segmentation_dtype) annotation_base = { i: state.roi_info.annotations.get(x) for i, x in enumerate(state.selected_components, start=1) } alternative_base = { name: cls._clip_data_array(roi_base, array) for name, array in state.roi_info.alternative.items() } components_parameters_dict = { i: state.roi_extraction_parameters[val] for i, val in enumerate(sorted(state.selected_components), 1) } base_chose = list(annotation_base.keys()) if new_segmentation_count == 0: return dataclasses.replace( state, roi_info=ROIInfo(roi=roi_base, annotations=annotation_base, alternative=alternative_base), selected_components=base_chose, roi_extraction_parameters=components_parameters_dict, ) new_segmentation = np.copy(new_roi_info.roi) new_segmentation[roi_base > 0] = 0 left_component_list = np.unique(new_segmentation.flat) if left_component_list[0] == 0: left_component_list = left_component_list[1:] new_segmentation = reduce_array(new_segmentation, dtype=segmentation_dtype) roi_base[new_segmentation > 0] = new_segmentation[new_segmentation > 0] + len(base_chose) for name, array in new_roi_info.alternative.items(): if name in alternative_base: alternative_base[name][new_segmentation > 0] = array[ new_segmentation > 0] else: alternative_base[name] = cls._clip_data_array( new_segmentation, array) for i, el in enumerate(left_component_list, start=len(base_chose) + 1): annotation_base[i] = new_roi_info.annotations.get(el) if el in list_of_components: base_chose.append(i) components_parameters_dict[i] = new_roi_extraction_parameters[el] roi_info = ROIInfo(roi=roi_base, annotations=annotation_base, alternative=alternative_base) return dataclasses.replace( state, roi_info=roi_info, selected_components=base_chose, roi_extraction_parameters=components_parameters_dict, )