Esempio n. 1
0
    def test_two_components(self):
        components = np.zeros((10, 10, 20), dtype=np.uint8)
        components[:] = 1
        components[2:8, 2:8, 2:18] = 0
        components[4:6, 4:6, 4:6] = 2
        components[4:6, 4:6, 14:16] = 3
        mu_arr = np.zeros(components.shape, dtype=np.float64)
        mu_arr[components == 0] = 0.5
        mu_arr[components > 1] = 1

        mso = PyMSO()
        neigh, dist = calculate_distances_array((1, 1, 1), NeighType.vertex)
        mso.set_neighbourhood(neigh, dist)
        mso.set_components(components)
        mso.set_mu_array(mu_arr)
        mso.set_components_num(3)

        mso.run_MSO(10)
        mso.steps_done()
        # res = mso.get_result_catted()
        arr = np.copy(components)
        arr[arr == 1] = 0
        arr[3:7, 3:7, 3:10] = 2
        arr[3:7, 3:7, 10:17] = 3
        # assert np.all(arr == res)

        mu_arr[2:8, 2:8, 10] = 0.08
        mso.set_mu_array(mu_arr)
        mso.run_MSO(10)
        # res = mso.get_result_catted()
        arr[2:8, 2:8, 2:10] = 2
        arr[2:8, 2:8, 11:18] = 3
        arr[3:7, 3:7, 10] = 0
        # assert np.all(arr == res)
        mu_arr[2:8, 2:8, 9] = 0.08
        mso.set_mu_array(mu_arr)
        arr[2:8, 2:8, 2:9] = 2
        arr[2:8, 2:8, 9] = 0
        arr[2:8, 2:8, 11:18] = 3
        mso.run_MSO(10)
        res = mso.get_result_catted()
        assert np.all(arr == res)
Esempio n. 2
0
class BaseMultiScaleOpening(TwoLevelThresholdBaseAlgorithm,
                            ABC):  # pragma: no cover
    @classmethod
    def get_fields(cls):
        return [
            AlgorithmProperty(
                "threshold",
                "Threshold",
                next(iter(double_threshold_dict.keys())),
                possible_values=double_threshold_dict,
                property_type=AlgorithmDescribeBase,
            ),
            AlgorithmProperty(
                "mu_mid",
                "Mu mid value",
                next(iter(mu_mid_dict.keys())),
                possible_values=mu_mid_dict,
                property_type=AlgorithmDescribeBase,
            ),
            AlgorithmProperty("step_limits",
                              "Limits of Steps",
                              100,
                              options_range=(1, 1000),
                              property_type=int),
        ] + super().get_fields()

    def get_info_text(self):
        return ("Threshold: " + ", ".join(map(str, self.threshold_info)) +
                "\nMid sizes: " + ", ".join(
                    map(str, self._sizes_array[1:self.components_num + 1])) +
                "\nFinal sizes: " + ", ".join(map(str, self.final_sizes[1:])) +
                f"\nsteps: {self.steps}")

    def __init__(self):
        super().__init__()
        self.finally_segment = None
        self.final_sizes = []
        self.threshold_info = [None, None]
        self.steps = 0
        self.mso = PyMSO()
        self.mso.set_use_background(True)

    def clean(self):
        self.sprawl_area = None
        self.mso = PyMSO()
        self.mso.set_use_background(True)
        super().clean()

    def set_image(self, image):
        super().set_image(image)
        self.threshold_info = [None, None]

    def calculation_run(self, report_fun) -> SegmentationResult:
        if self.new_parameters["side_connection"] != self.parameters[
                "side_connection"]:
            neigh, dist = calculate_distances_array(
                self.image.spacing,
                get_neigh(self.new_parameters["side_connection"]))
            self.mso.set_neighbourhood(neigh, dist)
        segment_data = super().calculation_run(report_fun)
        if segment_data is not None and self.components_num == 0:
            self.final_sizes = []
            return segment_data

        if segment_data is None:
            restarted = False
            finally_segment = np.copy(self.finally_segment)
        else:
            self.finally_segment = segment_data.roi
            finally_segment = segment_data.roi
            if np.max(finally_segment) > 250:
                raise SegmentationLimitException(
                    "Current implementation of MSO do not support more than 250 components"
                )
            components = finally_segment.astype(np.uint8)
            components[components > 0] += 1
            components[self.sprawl_area == 0] = 1
            self.mso.set_components(components, self.components_num)
            restarted = True

        if (restarted or self.old_threshold_info[1] != self.threshold_info[1]
                or self.new_parameters["mu_mid"] != self.parameters["mu_mid"]):
            if self.threshold_operator(self.threshold_info[1],
                                       self.threshold_info[0]):
                self.final_sizes = np.bincount(finally_segment.flat)
                return self.prepare_result(self.finally_segment)
            mu_calc: BaseMuMid = mu_mid_dict[self.new_parameters["mu_mid"]
                                             ["name"]]
            self.parameters["mu_mid"] = self.new_parameters["mu_mid"]
            sprawl_area = (self.sprawl_area > 0).astype(np.uint8)
            sprawl_area[finally_segment > 0] = 0
            mid_val = mu_calc.value(
                sprawl_area,
                self.channel,
                self.threshold_info[0],
                self.threshold_info[1],
                self.new_parameters["mu_mid"]["values"],
            )
            mu_array = calculate_mu_mid(self.channel, self.threshold_info[0],
                                        mid_val, self.threshold_info[1])
            self.mso.set_mu_array(mu_array)
            restarted = True

        if restarted or self.new_parameters["step_limits"] != self.parameters[
                "step_limits"]:
            self.parameters["step_limits"] = self.new_parameters["step_limits"]
            count_steps_factor = 20 if self.image.is_2d else 3
            self.mso.run_MSO(self.new_parameters["step_limits"],
                             count_steps_factor)
            self.steps = self.mso.steps_done()
            new_segment = self.mso.get_result_catted()
            new_segment[new_segment > 0] -= 1
            self.final_sizes = np.bincount(new_segment.flat)
            return self.prepare_result(new_segment)