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)
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)