Example #1
0
 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)},
     )
Example #2
0
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,
    )
Example #5
0
    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,
        )