예제 #1
0
 def test_simple_mask(self):
     mask_array = np.zeros((10, 20, 20), dtype=np.uint8)
     mask_array[3:7, 6:14, 6:14] = 1
     prop = MaskProperty(
         dilate=RadiusType.NO,
         dilate_radius=0,
         fill_holes=RadiusType.NO,
         max_holes_size=0,
         save_components=False,
         clip_to_mask=False,
     )
     new_mask = calculate_mask(prop, mask_array, None, (1, 1, 1))
     assert np.all(new_mask == mask_array)
     mask_array2 = np.copy(mask_array)
     mask_array2[4:6, 8:12, 8:12] = 2
     new_mask = calculate_mask(prop, mask_array2, None, (1, 1, 1))
     assert np.all(new_mask == mask_array)
     prop2 = MaskProperty(
         dilate=RadiusType.NO,
         dilate_radius=0,
         fill_holes=RadiusType.NO,
         max_holes_size=0,
         save_components=True,
         clip_to_mask=False,
     )
     new_mask = calculate_mask(prop2, mask_array2, None, (1, 1, 1))
     assert np.all(new_mask == mask_array2)
예제 #2
0
    def test_fill_holes_components(self):
        mask_base_array = np.zeros((20, 30, 30), dtype=np.uint8)
        mask_base_array[4:16, 6:15, 6:24] = 1
        mask_base_array[4:16, 15:24, 6:24] = 2
        res_mask1 = (mask_base_array > 0).astype(np.uint8)
        res_mask2 = np.copy(mask_base_array)
        mask_base_array[6:14, 8:12, 8:22] = 0
        mask_base_array[6:14, 18:22, 8:22] = 0
        prop1 = MaskProperty(
            dilate=RadiusType.NO,
            dilate_radius=0,
            fill_holes=RadiusType.R3D,
            max_holes_size=0,
            save_components=False,
            clip_to_mask=False,
        )
        prop2 = MaskProperty(
            dilate=RadiusType.NO,
            dilate_radius=0,
            fill_holes=RadiusType.R3D,
            max_holes_size=0,
            save_components=True,
            clip_to_mask=False,
        )
        new_mask = calculate_mask(prop1, mask_base_array, None, (1, 1, 1))
        assert np.all(new_mask == res_mask1)
        new_mask = calculate_mask(prop2, mask_base_array, None, (1, 1, 1))
        assert np.all(new_mask == res_mask2)

        mask_base_array[6:14, 14:16, 8:22] = 0
        res_mask2[6:14, 14:16, 8:22] = 0
        new_mask = calculate_mask(prop1, mask_base_array, None, (1, 1, 1))
        assert np.all(new_mask == res_mask1)
        new_mask = calculate_mask(prop2, mask_base_array, None, (1, 1, 1))
        assert np.all(new_mask == res_mask2)
예제 #3
0
    def test_fill_holes(self):
        mask_base_array = np.zeros((1, 20, 30, 30), dtype=np.uint8)
        mask_base_array[:, 4:16, 8:22, 8:22] = 1
        mask1_array = np.copy(mask_base_array)
        mask1_array[:, 4:16, 10:15, 10:15] = 0
        prop = MaskProperty(
            dilate=RadiusType.NO,
            dilate_radius=0,
            fill_holes=RadiusType.R2D,
            max_holes_size=0,
            save_components=False,
            clip_to_mask=False,
        )
        new_mask = calculate_mask(prop, mask1_array, None, (1, 1, 1))
        assert np.all(mask_base_array == new_mask)

        prop = MaskProperty(
            dilate=RadiusType.NO,
            dilate_radius=0,
            fill_holes=RadiusType.R3D,
            max_holes_size=0,
            save_components=False,
            clip_to_mask=False,
        )
        new_mask = calculate_mask(prop, mask1_array, None, (1, 1, 1))
        assert np.all(mask1_array == new_mask)

        mask2_array = np.copy(mask1_array)
        mask2_array[:, 5:15, 10:15, 17:20] = 0
        new_mask = calculate_mask(prop, mask2_array, None, (1, 1, 1))
        assert np.all(mask1_array == new_mask)
예제 #4
0
    def test_fill_holes_size(self):
        mask_base_array = np.zeros((1, 20, 20, 40), dtype=np.uint8)
        mask_base_array[0, 2:18, 2:18, 4:36] = 1
        mask_base_array[0, 4:16, 4:16, 6:18] = 0
        mask1_array = np.copy(mask_base_array)
        mask1_array[0, 6:14, 6:14, 24:32] = 0

        prop1 = MaskProperty(
            dilate=RadiusType.NO,
            dilate_radius=0,
            fill_holes=RadiusType.R2D,
            max_holes_size=70,
            save_components=False,
            clip_to_mask=False,
        )
        prop2 = MaskProperty(
            dilate=RadiusType.NO,
            dilate_radius=0,
            fill_holes=RadiusType.R3D,
            max_holes_size=530,
            save_components=True,
            clip_to_mask=False,
        )

        new_mask = calculate_mask(prop1, mask_base_array, None, (1, 1, 1))
        assert np.all(new_mask == mask_base_array)
        new_mask = calculate_mask(prop2, mask_base_array, None, (1, 1, 1))
        assert np.all(new_mask == mask_base_array)
예제 #5
0
 def test_reversed_mask(self):
     mask_base_array = np.zeros((30, 30, 30), dtype=np.uint8)
     mask_base_array[10:20, 10:20, 10:20] = 1
     mask2_array = np.copy(mask_base_array)
     mask2_array[13:17, 13:17, 13:17] = 0
     prop1 = MaskProperty(
         dilate=RadiusType.NO,
         dilate_radius=-0,
         fill_holes=RadiusType.NO,
         max_holes_size=0,
         save_components=False,
         clip_to_mask=False,
         reversed_mask=False,
     )
     prop2 = MaskProperty(
         dilate=RadiusType.NO,
         dilate_radius=-0,
         fill_holes=RadiusType.NO,
         max_holes_size=0,
         save_components=False,
         clip_to_mask=False,
         reversed_mask=True,
     )
     new_mask1 = calculate_mask(prop1, mask_base_array, mask2_array,
                                (1, 1, 1))
     new_mask2 = calculate_mask(prop2, mask_base_array, mask2_array,
                                (1, 1, 1))
     assert np.all(new_mask1 == mask_base_array)
     assert np.all(new_mask2 == (mask_base_array == 0))
예제 #6
0
 def test_single(self):
     mask = np.zeros((10, 10, 10), dtype=np.uint8)
     mask[2:8, 2:8, 2:8] = 1
     mask2 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.NO, -1, False, True),
         mask, None, (1, 1, 1))
     assert np.all(mask2 == mask)
     mask3 = np.copy(mask)
     mask3[mask > 0] = 2
     mask2 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.NO, -1, False, True),
         mask, None, (1, 1, 1))
     assert np.all(mask2 == mask)
예제 #7
0
 def test_dilate(self):
     mask = np.zeros((1, 10, 10, 10), dtype=np.uint8)
     mask[0, 2:8, 2:8, 2:8] = 1
     mask2 = calculate_mask(
         MaskProperty(RadiusType.R3D, -1, RadiusType.NO, -1, False, True),
         mask, None, (1, 1, 1))
     mask3 = np.zeros((1, 10, 10, 10), dtype=np.uint8)
     mask3[0, 3:7, 3:7, 3:7] = 1
     assert np.all(mask2 == mask3)
     mask2 = calculate_mask(
         MaskProperty(RadiusType.R2D, -1, RadiusType.NO, -1, False, True),
         mask, None, (1, 1, 1))
     mask3 = np.zeros((1, 10, 10, 10), dtype=np.uint8)
     mask3[0, 2:8, 3:7, 3:7] = 1
     assert np.all(mask2 == mask3)
예제 #8
0
 def test_mask_property_combinations(self, dilate, radius, fill_holes,
                                     max_holes_size, save_components,
                                     clip_to_mask, reversed_mask, old_mask):
     mask = np.zeros((1, 6, 6, 15), dtype=np.uint8)
     im = Image(data=mask.copy(),
                image_spacing=(3, 1, 1),
                file_path="",
                axes_order="TZYX")
     mask[:, 1:-1, 1:-1, 2:5] = 1
     mask[:, 2:-2, 2:-2, 3:4] = 0
     mask[:, 1:-1, 1:-1, 6:9] = 2
     mask[:, 2:-2, 2:-2, 7:8] = 0
     mask[:, 1:-1, 1:-1, 10:13] = 3
     mask[:, 2:-2, 2:-2, 11:12] = 0
     mask = im.fit_mask_to_image(mask)
     assert np.all(np.unique(mask.flat) == [0, 1, 2, 3])
     _old_mask = np.zeros(mask.shape,
                          dtype=mask.dtype) if old_mask else None
     mp = MaskProperty(
         dilate=dilate,
         dilate_radius=radius,
         fill_holes=fill_holes,
         max_holes_size=max_holes_size,
         save_components=save_components,
         clip_to_mask=clip_to_mask,
         reversed_mask=reversed_mask,
     )
     mask1 = calculate_mask(mp,
                            mask,
                            _old_mask,
                            im.spacing,
                            time_axis=im.time_pos)
     assert mask1.shape == mask.shape
예제 #9
0
 def test_save_component_fill_holes_problematic(self):
     mask = np.zeros((12, 12, 12), dtype=np.uint8)
     mask[2:7, 2:-2, 2:-2] = 3
     mask[7:-2, 2:-2, 2:-2] = 2
     mask[4:-4, 4:-4, 4:-4] = 1
     mask2 = np.copy(mask)
     mask2[5, 5, 5] = 0
     mask2[3, 3, 3] = 0
     mask1 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.R2D, -1, True, True),
         mask2, None, (1, 1, 1))
     assert np.all(mask == mask1)
     mask1 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.R3D, -1, True, True),
         mask2, None, (1, 1, 1))
     assert np.all(mask == mask1)
예제 #10
0
def calculate_pipeline(image: Image, mask: typing.Optional[np.ndarray],
                       pipeline: SegmentationPipeline, report_fun):
    history = []
    report_fun("max", 2 * len(pipeline.mask_history) + 1)
    for i, el in enumerate(pipeline.mask_history):
        result, _ = calculate_segmentation_step(el.segmentation, image, mask)
        segmentation = image.fit_array_to_image(result.roi)
        report_fun("step", 2 * i + 1)
        new_mask = calculate_mask(
            mask_description=el.mask_property,
            segmentation=segmentation,
            old_mask=mask,
            spacing=image.spacing,
            time_axis=image.time_pos,
        )
        segmentation_parameters = {
            "algorithm_name": el.segmentation.name,
            "values": el.segmentation.values
        }
        history.append(
            HistoryElement.create(segmentation, mask, segmentation_parameters,
                                  el.mask_property))
        report_fun("step", 2 * i + 2)
        mask = image.fit_array_to_image(new_mask)
    result, text = calculate_segmentation_step(pipeline.segmentation, image,
                                               mask)
    report_fun("step", 2 * len(pipeline.mask_history) + 1)
    return PipelineResult(result.roi, result.additional_layers, mask, history,
                          text)
예제 #11
0
    def step_mask_create(self, operation: MaskCreate,
                         children: List[CalculationTree]):
        """
        Create mask from current segmentation state using definition

        :param MaskCreate operation: mask create description.
        :param List[CalculationTree] children: list of nodes to iterate over after perform segmentation
        """
        mask = calculate_mask(
            mask_description=operation.mask_property,
            segmentation=self.segmentation,
            old_mask=self.mask,
            spacing=self.image.spacing,
            time_axis=self.image.time_pos,
        )
        if operation.name in self.reused_mask:
            self.mask_dict[operation.name] = mask
        history_element = HistoryElement.create(
            self.segmentation,
            self.mask,
            self.algorithm_parameters,
            operation.mask_property,
        )
        backup = self.mask, self.history
        self.mask = mask
        self.history.append(history_element)
        self.iterate_over(children)
        self.mask, self.history = backup
예제 #12
0
 def test_fil_holes_2d(self):
     mask = np.zeros((10, 10, 10), dtype=np.uint8)
     mask[2:8, 2:8, 2:8] = 1
     mask2 = np.copy(mask)
     mask2[:, 4:6, 4:6] = 0
     mask3 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.R2D, -1, False, True),
         mask2, None, (1, 1, 1))
     assert np.all(mask3 == mask)
     mask3 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.R2D, 3, False, True),
         mask2, None, (1, 1, 1))
     assert np.all(mask3 == mask2)
     mask3 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.R2D, 4, False, True),
         mask2, None, (1, 1, 1))
     assert np.all(mask3 == mask)
예제 #13
0
    def test_dilate_spacing_positive(self):
        mask_base_array = np.zeros((1, 30, 30, 30), dtype=np.uint8)
        mask_base_array[:, 10:20, 10:20, 10:20] = 1
        prop1 = MaskProperty(
            dilate=RadiusType.R3D,
            dilate_radius=1,
            fill_holes=RadiusType.NO,
            max_holes_size=70,
            save_components=False,
            clip_to_mask=False,
        )
        prop2 = MaskProperty(
            dilate=RadiusType.R3D,
            dilate_radius=2,
            fill_holes=RadiusType.NO,
            max_holes_size=70,
            save_components=False,
            clip_to_mask=False,
        )
        prop3 = MaskProperty(
            dilate=RadiusType.R3D,
            dilate_radius=3,
            fill_holes=RadiusType.NO,
            max_holes_size=70,
            save_components=False,
            clip_to_mask=False,
        )
        res_array1 = np.zeros((30, 30, 30), dtype=np.uint8)
        res_array1[10:20, 9:21, 9:21] = 1
        new_mask = calculate_mask(prop1, mask_base_array, None, (3, 1, 1))
        assert np.all(new_mask[0] == res_array1)
        res_array2 = np.zeros((30, 30, 30), dtype=np.uint8)
        res_array2[10:20, 8:22, 8:22] = 1
        res_array2[(9, 20), 9:21, 9:21] = 1
        res_array2[:, (8, 21, 8, 21), (8, 8, 21, 21)] = 0
        new_mask = calculate_mask(prop2, mask_base_array, None, (3, 1, 1))
        assert np.all(new_mask[0] == res_array2)
        res_array3 = np.zeros((30, 30, 30), dtype=np.uint8)
        res_array3[(9, 20), 8:22, 9:21] = 1
        res_array3[(9, 9, 20, 20), 9:21, (8, 21, 8, 21)] = 1

        res_array3[10:20, 7:23, 9:21] = 1
        res_array3[10:20, 8:22, (8, 21)] = 1
        res_array3[10:20, 9:21, (7, 22)] = 1
        new_mask = calculate_mask(prop3, mask_base_array, None, (3, 1, 1))
        assert np.all(new_mask == res_array3)
예제 #14
0
 def test_fil_holes_3d_torus(self):
     mask = np.zeros((1, 10, 10, 10), dtype=np.uint8)
     mask[0, 2:8, 2:8, 2:8] = 1
     mask[0, :, 4:6, 4:6] = 0
     mask2 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.R3D, -1, False, True),
         mask, None, (1, 1, 1))
     assert np.all(mask2 == mask)
예제 #15
0
 def test_reverse(self):
     mask = np.zeros((10, 10, 10), dtype=np.uint8)
     mask[3:7, 3:7, 3:7] = 1
     mask2 = np.ones((10, 10, 10), dtype=np.uint8)
     mask2[mask > 0] = 0
     mask3 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.NO, -1, False, True,
                      True), mask, None, (1, 1, 1))
     assert np.all(mask3 == mask2)
예제 #16
0
 def test_chose_components(self):
     mask = np.zeros((12, 12, 12), dtype=np.uint8)
     mask[2:7, 2:-2, 2:-2] = 3
     mask[7:-2, 2:-2, 2:-2] = 2
     mask[4:-4, 4:-4, 4:-4] = 1
     mask1 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.R2D, -1, True, True),
         mask, None, (1, 1, 1), [1, 3])
     assert np.all(np.unique(mask1) == [0, 1, 3])
예제 #17
0
 def test_save_components(self):
     mask = np.zeros((10, 10, 10), dtype=np.uint8)
     mask[2:8, 2:8, 2:8] = 1
     mask2 = np.copy(mask)
     mask2[2:8, 4:6, 4:6] = 2
     mask3 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.NO, -1, False, True),
         mask2, None, (1, 1, 1))
     assert np.all(mask3 == mask)
     mask3 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.NO, -1, True, True),
         mask2, None, (1, 1, 1))
     assert np.all(mask3 == mask2)
     mask4 = np.copy(mask2)
     mask4[mask4 == 2] = 3
     mask3 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.NO, -1, True, True),
         mask4, None, (1, 1, 1))
     assert np.all(mask3 == mask4)
예제 #18
0
 def test_clip(self):
     mask = np.zeros((10, 10, 10), dtype=np.uint8)
     mask[3:7, 3:7, 3:7] = 1
     mask2 = calculate_mask(
         MaskProperty(RadiusType.R3D, 1, RadiusType.NO, -1, False, True),
         mask, mask, (1, 1, 1))
     assert np.all(mask == mask2)
     mask2[:, 4:6, 4:6] = 0
     mask3 = calculate_mask(
         MaskProperty(RadiusType.R3D, 1, RadiusType.NO, -1, False, True),
         mask, mask2, (1, 1, 1))
     assert np.all(mask3 == mask2)
     mask2[:] = 0
     mask2[4:6, 4:6, 4:6] = 1
     mask3 = calculate_mask(
         MaskProperty(RadiusType.NO, 0, RadiusType.NO, -1, False, True,
                      True), mask2, mask, (1, 1, 1))
     mask[mask2 == 1] = 0
     assert np.all(mask3 == mask)
예제 #19
0
def test_pipeline_manual(image, algorithm_parameters, mask_property):
    algorithm = analysis_algorithm_dict[
        algorithm_parameters["algorithm_name"]]()
    algorithm.set_image(image)
    algorithm.set_parameters(**algorithm_parameters["values"])
    result = algorithm.calculation_run(lambda x, y: None)
    mask = calculate_mask(mask_property, result.roi, None, image.spacing)
    algorithm_parameters["values"]["channel"] = 1
    algorithm.set_parameters(**algorithm_parameters["values"])
    algorithm.set_mask(mask)
    result2 = algorithm.calculation_run(lambda x, y: None)
    assert np.max(result2.roi) == 2
예제 #20
0
 def test_time_axis(self, time):
     mask = np.zeros((time, 6, 6, 6), dtype=np.uint8)
     mask[:, 1:-1, 1:-1, 2:5] = 1
     mask[:, 2:-2, 2:-2, 3:4] = 0
     mp = MaskProperty(
         dilate=RadiusType.NO,
         dilate_radius=0,
         fill_holes=RadiusType.NO,
         max_holes_size=-1,
         save_components=False,
         clip_to_mask=False,
     )
     mask1 = calculate_mask(mp, mask, None, (1, 1, 1))
     assert mask1.shape == mask.shape
예제 #21
0
    def test_dilate_spacing_negative(self, radius):
        mask_base_array = np.zeros((1, 30, 30, 30), dtype=np.uint8)
        mask_base_array[:, 10:20, 5:25, 5:25] = 1
        res_array1 = np.zeros((1, 30, 30, 30), dtype=np.uint8)
        s = slice(10, 20) if radius == -1 else slice(11, 19)
        res_array1[:, s, 5 - radius:25 + radius, 5 - radius:25 + radius] = 1

        prop1 = MaskProperty(
            dilate=RadiusType.R3D,
            dilate_radius=radius,
            fill_holes=RadiusType.NO,
            max_holes_size=70,
            save_components=False,
            clip_to_mask=False,
        )
        new_mask = calculate_mask(prop1, mask_base_array, None, (3, 1, 1))
        assert np.all(new_mask == res_array1)
예제 #22
0
def calculate_mask_from_project(
    mask_description: MaskProperty, project: ProjectInfoBase, components: Optional[List[int]] = None
) -> np.ndarray:
    """
    Function for calculate mask base on MaskProperty.
    This function calls :py:func:`calculate_mask` with arguments from project.

    :param MaskProperty mask_description: information how calculate mask
    :param ProjectInfoBase project: project with information about segmentation
    :param Optional[List[int]] components: If present inform which components
        should be used when calculation mask, otherwise use all.
    :return: new mask
    :rtype: np.ndarray
    """
    try:
        time_axis = project.image.time_pos
    except AttributeError:
        time_axis = None
    return calculate_mask(
        mask_description, project.roi_info.roi, project.mask, project.image.spacing, components, time_axis
    )
예제 #23
0
    def create_mask(self):
        if self.roi_select.value is None:
            return
        layer_name = self.name.text()
        self.settings.set("mask_create_name", layer_name)
        mask_property = self.mask_widget.get_mask_property()
        if mask_property.clip_to_mask and self.mask_select.value is None:
            warnings.warn("Select base mask", RuntimeWarning)
            return
        base_mask = None if self.mask_select.value is None else self.mask_select.value.data
        scale = np.array(self.roi_select.value.scale)
        mask = np.array(calculate_mask(mask_property, self.roi_select.value.data, base_mask, scale[-3:]))
        if layer_name in self.viewer.layers:
            self.viewer.layers[layer_name].data = mask
        else:
            self.viewer.add_labels(
                mask,
                scale=scale[-int(mask.ndim) :],
                name=layer_name,
            )

        self.settings.dump()
예제 #24
0
 def test_dilate(self, radius_type, radius, time):
     mask_base_array = np.zeros((time, 30, 30, 30), dtype=np.uint8)
     mask_base_array[:, 10:20, 10:20, 10:20] = 1
     prop1 = MaskProperty(
         dilate=radius_type,
         dilate_radius=radius,
         fill_holes=RadiusType.NO,
         max_holes_size=70,
         save_components=False,
         clip_to_mask=False,
     )
     res_array1 = np.zeros((1, 30, 30, 30), dtype=np.uint8)
     slices: List[Union[int, slice]] = [slice(None)] * 4
     for i in range(1, 4):
         slices[i] = slice(10 - radius, 20 + radius)
     if radius_type == RadiusType.R2D:
         slices[1] = slice(10, 20)
     res_array1[tuple(slices)] = 1
     if radius_type == RadiusType.R3D:
         res_array1[:, (9, 9, 9, 9), (9, 9, 20, 20), (9, 20, 20, 9)] = 0
         res_array1[:, (20, 20, 20, 20), (9, 9, 20, 20), (9, 20, 20, 9)] = 0
     new_mask = calculate_mask(prop1, mask_base_array, None, (1, 1, 1))
     assert np.all(new_mask == res_array1)