Пример #1
0
 def run(self, ips, imgs, para=None):
     flood_fill(imgs,
                para['seed'],
                para['color'],
                connectivity=para['conn'],
                tolerance=para['tor'],
                inplace=True)
Пример #2
0
def test_selem():
    # Basic tests for nonstandard structuring elements
    selem = np.array([[0, 1, 1],
                      [0, 1, 1],
                      [0, 0, 0]])  # Cannot grow left or down

    output = flood_fill(np.zeros((5, 6), dtype=np.uint8), (3, 1), 255,
                        selem=selem)

    expected = np.array([[0, 255, 255, 255, 255, 255],
                         [0, 255, 255, 255, 255, 255],
                         [0, 255, 255, 255, 255, 255],
                         [0, 255, 255, 255, 255, 255],
                         [0,   0,   0,   0,   0,   0]], dtype=np.uint8)

    np.testing.assert_equal(output, expected)

    selem = np.array([[0, 0, 0],
                      [1, 1, 0],
                      [1, 1, 0]])  # Cannot grow right or up

    output = flood_fill(np.zeros((5, 6), dtype=np.uint8), (1, 4), 255,
                        selem=selem)

    expected = np.array([[  0,   0,   0,   0,   0,   0],
                         [255, 255, 255, 255, 255,   0],
                         [255, 255, 255, 255, 255,   0],
                         [255, 255, 255, 255, 255,   0],
                         [255, 255, 255, 255, 255,   0]], dtype=np.uint8)

    np.testing.assert_equal(output, expected)
Пример #3
0
def generateCosts(diffImg, mask):
    costsArr = np.ones_like(diffImg)
    row, col = mask.nonzero()
    c = (col.min(), col.max())
    shape = mask.shape

    lbls = mask.copy().astype(np.uint8)
    cslice = slice(c[0], c[1] + 1)
    submask = np.ascontiguousarray(lbls[:, cslice])
    submask = flood_fill(submask, (0, 0), 2)
    submask = flood_fill(submask, (shape[0] - 1, 0), 3)
    lbls[:, cslice] = submask

    upper = (lbls == 2).sub(axis=0).astype(np.float64)
    lower = (lbls == 3).sub(axis=0).astype(np.float64)

    ugood = np.abs(np.gradient(upper[cslice])) < 2.0
    lgood = np.abs(np.gradient(lower[cslice])) < 2.0

    costsUpper = np.ones_like(upper)
    costsLower = np.ones_like(lower)
    costsUpper[cslice][ugood] = upper[cslice].min() / np.maximum(
        upper[cslice][ugood], 1)
    costsLower[cslice][lgood] = lower[cslice].min() / np.maximim(
        lower[cslice][lgood], 1)

    vdist = mask.shape[0]
    costUpper = costsUpper[np.newaxis, :].repeat(vdist, axis=0)
    costLower = costsLower[np.newaxis, :].repeat(vdist, axis=0)

    costsArr[:, cslice] = costsUpper[:, cslice] * (lbls[:, cslice] == 2)
    costsArr[:, cslice] += costsLower[:, cslice] * (lbls[:, cslice] == 3)
    costsArr[mask] = diffImg[mask]
    return costsArr
Пример #4
0
def test_selem():
    # Basic tests for nonstandard structuring elements
    selem = np.array([[0, 1, 1], [0, 1, 1], [0, 0,
                                             0]])  # Cannot grow left or down

    output = flood_fill(np.zeros((5, 6), dtype=np.uint8), (3, 1),
                        255,
                        selem=selem)

    expected = np.array(
        [[0, 255, 255, 255, 255, 255], [0, 255, 255, 255, 255, 255],
         [0, 255, 255, 255, 255, 255], [0, 255, 255, 255, 255, 255],
         [0, 0, 0, 0, 0, 0]],
        dtype=np.uint8)

    np.testing.assert_equal(output, expected)

    selem = np.array([[0, 0, 0], [1, 1, 0], [1, 1,
                                             0]])  # Cannot grow right or up

    output = flood_fill(np.zeros((5, 6), dtype=np.uint8), (1, 4),
                        255,
                        selem=selem)

    expected = np.array(
        [[0, 0, 0, 0, 0, 0], [255, 255, 255, 255, 255, 0],
         [255, 255, 255, 255, 255, 0], [255, 255, 255, 255, 255, 0],
         [255, 255, 255, 255, 255, 0]],
        dtype=np.uint8)

    np.testing.assert_equal(output, expected)
Пример #5
0
 def removeAllHoles(self, img: np.ndarray, x: int = 0, y: int = 0):
     print('fill in empty spaces in objects...')
     tmp = np.array(img, np.uint8)
     original = tmp.copy()
     flood_fill(tmp, (x, y), 1, inplace=True)
     tmp = self.getInverse(tmp)
     return np.logical_or(tmp, original)
Пример #6
0
    def __isolate_lung(self, seg):
        """
        Segment the lung in the body
        :param seg: the segmentation of the human body
        :return: segmentation of lung
        """
        # take only the parts that contain air
        cut_seg = np.zeros((seg.shape))
        new_seg1 = np.zeros((seg.shape))
        new_seg1[:, :, :] = 1 - seg[:, :, :]
        new_seg = binary_closing(np.copy(new_seg1), np.ones((3, 3, 3)))

        # delete air that is outside the body
        m_ax = (new_seg.shape[2] * 1) // 2
        cut_seg[:, :, m_ax:] = np.copy(new_seg[:, :, m_ax:])
        cut_seg[:, :, m_ax:] = flood_fill(cut_seg[:, :, m_ax:], (0, 0, 0), 2)
        cut_seg[:, :,
                m_ax:] = flood_fill(cut_seg[:, :, m_ax:],
                                    (cut_seg[:, :, m_ax:].shape[0] - 1,
                                     cut_seg[:, :, m_ax:].shape[1] - 1, 0), 3)
        new_seg[np.where((cut_seg == 2) | (cut_seg == 3))] = 0
        reg_seg = np.copy(new_seg)
        new_seg[:, :, m_ax:] = self.__choose_largest_co_component(
            np.copy(reg_seg[:, :, m_ax:]), 1)
        new_seg[:, :, :m_ax] = 0

        return new_seg
Пример #7
0
def test_inplace_noncontiguous():
    image = np.array([[0, 0, 0, 0, 0, 0, 0],
                      [0, 1, 1, 0, 2, 2, 0],
                      [0, 1, 1, 0, 2, 2, 0],
                      [1, 0, 0, 0, 0, 0, 3],
                      [0, 1, 1, 1, 3, 3, 4]])

    # Transpose is noncontiguous
    image2 = image[::2, ::2]

    flood_fill(image2, (0, 0), 5, in_place=True)

    # The inplace modified result
    expected2 = np.array([[5, 5, 5, 5],
                          [5, 1, 2, 5],
                          [5, 1, 3, 4]])

    np.testing.assert_allclose(image2, expected2)

    # Projected back through the view, `image` also modified
    expected = np.array([[5, 0, 5, 0, 5, 0, 5],
                         [0, 1, 1, 0, 2, 2, 0],
                         [5, 1, 1, 0, 2, 2, 5],
                         [1, 0, 0, 0, 0, 0, 3],
                         [5, 1, 1, 1, 3, 3, 4]])

    np.testing.assert_allclose(image, expected)
Пример #8
0
def test_footprint():
    # Basic tests for nonstandard footprints
    footprint = np.array([[0, 1, 1], [0, 1, 1],
                          [0, 0, 0]])  # Cannot grow left or down

    output = flood_fill(np.zeros((5, 6), dtype=np.uint8), (3, 1),
                        255,
                        footprint=footprint)

    expected = np.array(
        [[0, 255, 255, 255, 255, 255], [0, 255, 255, 255, 255, 255],
         [0, 255, 255, 255, 255, 255], [0, 255, 255, 255, 255, 255],
         [0, 0, 0, 0, 0, 0]],
        dtype=np.uint8)

    np.testing.assert_equal(output, expected)

    footprint = np.array([[0, 0, 0], [1, 1, 0],
                          [1, 1, 0]])  # Cannot grow right or up

    output = flood_fill(np.zeros((5, 6), dtype=np.uint8), (1, 4),
                        255,
                        footprint=footprint)

    expected = np.array(
        [[0, 0, 0, 0, 0, 0], [255, 255, 255, 255, 255, 0],
         [255, 255, 255, 255, 255, 0], [255, 255, 255, 255, 255, 0],
         [255, 255, 255, 255, 255, 0]],
        dtype=np.uint8)

    np.testing.assert_equal(output, expected)
Пример #9
0
def test_non_adjacent_footprint():
    # Basic tests for non-adjacent footprints
    footprint = np.array([[1, 0, 0, 0, 1], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0],
                          [0, 0, 0, 0, 0], [1, 0, 0, 0, 1]])

    output = flood_fill(np.zeros((5, 6), dtype=np.uint8), (2, 3),
                        255,
                        footprint=footprint)

    expected = np.array(
        [[0, 255, 0, 0, 0, 255], [0, 0, 0, 0, 0, 0], [0, 0, 0, 255, 0, 0],
         [0, 0, 0, 0, 0, 0], [0, 255, 0, 0, 0, 255]],
        dtype=np.uint8)

    np.testing.assert_equal(output, expected)

    footprint = np.array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1],
                          [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]])

    image = np.zeros((5, 10), dtype=np.uint8)
    image[:, (3, 7, 8)] = 100

    output = flood_fill(image, (0, 0), 255, footprint=footprint)

    expected = np.array([[255, 255, 255, 100, 255, 255, 255, 100, 100, 0],
                         [255, 255, 255, 100, 255, 255, 255, 100, 100, 0],
                         [255, 255, 255, 100, 255, 255, 255, 100, 100, 0],
                         [255, 255, 255, 100, 255, 255, 255, 100, 100, 0],
                         [255, 255, 255, 100, 255, 255, 255, 100, 100, 0]],
                        dtype=np.uint8)

    np.testing.assert_equal(output, expected)
Пример #10
0
def test_inplace_noncontiguous():
    image = np.array([[0, 0, 0, 0, 0, 0, 0],
                      [0, 1, 1, 0, 2, 2, 0],
                      [0, 1, 1, 0, 2, 2, 0],
                      [1, 0, 0, 0, 0, 0, 3],
                      [0, 1, 1, 1, 3, 3, 4]])

    # Transpose is noncontiguous
    image2 = image[::2, ::2]

    flood_fill(image2, (0, 0), 5, inplace=True)

    # The inplace modified result
    expected2 = np.array([[5, 5, 5, 5],
                          [5, 1, 2, 5],
                          [5, 1, 3, 4]])

    np.testing.assert_allclose(image2, expected2)

    # Projected back through the view, `image` also modified
    expected = np.array([[5, 0, 5, 0, 5, 0, 5],
                         [0, 1, 1, 0, 2, 2, 0],
                         [5, 1, 1, 0, 2, 2, 5],
                         [1, 0, 0, 0, 0, 0, 3],
                         [5, 1, 1, 1, 3, 3, 4]])

    np.testing.assert_allclose(image, expected)
Пример #11
0
def test_1d():
    image = np.arange(11)
    expected = np.array([0, 1, -20, -20, -20, -20, -20, -20, -20, 9, 10])

    output = flood_fill(image, 5, -20, tolerance=3)
    output2 = flood_fill(image, (5, ), -20, tolerance=3)

    np.testing.assert_equal(output, expected)
    np.testing.assert_equal(output, output2)
Пример #12
0
def test_1d():
    image = np.arange(11)
    expected = np.array([0, 1, -20, -20, -20, -20, -20, -20, -20, 9, 10])

    output = flood_fill(image, 5, -20, tolerance=3)
    output2 = flood_fill(image, (5,), -20, tolerance=3)

    np.testing.assert_equal(output, expected)
    np.testing.assert_equal(output, output2)
Пример #13
0
def test_inplace_int():
    image = np.array([[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 2, 2, 0],
                      [0, 1, 1, 0, 2, 2, 0], [1, 0, 0, 0, 0, 0, 3],
                      [0, 1, 1, 1, 3, 3, 4]])

    flood_fill(image, (0, 0), 5, inplace=True)

    expected = np.array([[5, 5, 5, 5, 5, 5, 5], [5, 1, 1, 5, 2, 2, 5],
                         [5, 1, 1, 5, 2, 2, 5], [1, 5, 5, 5, 5, 5, 3],
                         [5, 1, 1, 1, 3, 3, 4]])

    np.testing.assert_array_equal(image, expected)
Пример #14
0
def global_out_fill(img, r, c, color):
    img = img.reshape((img.shape + (1, ))[:3])
    ori = np.ones(img.shape[:2], dtype=np.bool)
    for i in range(img.shape[2]):
        ori &= flood(img[:, :, i], (r, c), connectivity=2)
    filled = binary_fill_holes(ori)
    dilation = binary_dilation(ori)
    dilation ^= filled
    rs, cs = np.where(dilation)
    if len(rs) == 0: return
    msk = ((img == img[r, c]).min(axis=2)).astype(np.uint8)
    flood_fill(msk, (rs[0], cs[0]), 2, connectivity=2, inplace=True)
    img[msk == 2] = color
Пример #15
0
def test_inplace_float():
    image = np.array(
        [[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 2, 2, 0], [0, 1, 1, 0, 2, 2, 0],
         [1, 0, 0, 0, 0, 0, 3], [0, 1, 1, 1, 3, 3, 4]],
        dtype=np.float32)

    flood_fill(image, (0, 0), 5, inplace=True)

    expected = np.array(
        [[5., 5., 5., 5., 5., 5., 5.], [5., 1., 1., 5., 2., 2., 5.],
         [5., 1., 1., 5., 2., 2., 5.], [1., 5., 5., 5., 5., 5., 3.],
         [5., 1., 1., 1., 3., 3., 4.]],
        dtype=np.float32)

    np.testing.assert_allclose(image, expected)
Пример #16
0
def test_inplace_int_deprecated():
    """This test is deprecated and will be removed in
    version 0.19.0. See #4248.
    """
    image = np.array([[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 2, 2, 0],
                      [0, 1, 1, 0, 2, 2, 0], [1, 0, 0, 0, 0, 0, 3],
                      [0, 1, 1, 1, 3, 3, 4]])

    with expected_warnings(['The `inplace`']):
        flood_fill(image, (0, 0), 5, inplace=True)

    expected = np.array([[5, 5, 5, 5, 5, 5, 5], [5, 1, 1, 5, 2, 2, 5],
                         [5, 1, 1, 5, 2, 2, 5], [1, 5, 5, 5, 5, 5, 3],
                         [5, 1, 1, 1, 3, 3, 4]])

    np.testing.assert_array_equal(image, expected)
Пример #17
0
def test_overrange_tolerance_int():
    image = np.arange(256, dtype=np.uint8).reshape((8, 8, 4))
    expected = np.zeros_like(image)

    output = flood_fill(image, (7, 7, 3), 0, tolerance=379)

    np.testing.assert_equal(output, expected)
Пример #18
0
    def action_flood_contiguous(self, label, frame, x_location, y_location):
        """Flood fill a cell with a unique new label.

        Alternative to watershed for fixing duplicate labels of
        non-touching objects.
        """
        img_ann = self.annotated[frame, ..., self.feature]
        old_label = label
        new_label = self.get_max_label() + 1

        in_original = np.any(np.isin(img_ann, old_label))

        filled_img_ann = flood_fill(img_ann,
                                    (int(y_location / self.scale_factor),
                                     int(x_location / self.scale_factor)),
                                    new_label)
        self.annotated[frame, ..., self.feature] = filled_img_ann

        in_modified = np.any(np.isin(filled_img_ann, old_label))

        # update cell info dicts since labels are changing
        self.add_cell_info(add_label=new_label, frame=frame)

        if in_original and not in_modified:
            self.del_cell_info(del_label=old_label, frame=frame)
Пример #19
0
    def action_flood(self, label, x_location, y_location):
        """
        Floods the region at (x, y) with the label.
        Only floods diagonally connected pixels (connectivity == 2) when label != 0.

        Args:
            label (int): label to fill region with
            x_location (int): x coordinate of region to flood
            y_location (int): y coordinate of region to flood
        """
        label = self.clean_label(label)

        img = self.frame[..., self.feature]
        # Rescale click location to corresponding location in label array
        hole_fill_seed = (int(y_location), int(x_location))
        # Check current label
        old_label = img[hole_fill_seed]

        # Flood region with label
        # helps prevents hole fill from spilling into background
        connectivity = 1 if old_label == 0 else 2
        flooded = flood_fill(img, hole_fill_seed, label, connectivity=connectivity)

        # Update cell info dicts
        label_in_original = np.any(np.isin(label, img))
        label_in_flooded = np.any(np.isin(label, flooded))
        old_label_in_flooded = np.any(np.isin(old_label, flooded))

        if label != 0 and not label_in_original and label_in_flooded:
            self.add_cell_info(add_label=label, frame=self.frame_id)
        if old_label != 0 and not old_label_in_flooded:
            self.del_cell_info(del_label=old_label, frame=self.frame_id)

        self.frame[..., self.feature] = flooded
        self.y_changed = True
Пример #20
0
def test_overrange_tolerance_int():
    image = np.arange(256, dtype=np.uint8).reshape((8, 8, 4))
    expected = np.zeros_like(image)

    output = flood_fill(image, (7, 7, 3), 0, tolerance=379)

    np.testing.assert_equal(output, expected)
Пример #21
0
def test_inplace_int():
    image = np.array([[0, 0, 0, 0, 0, 0, 0],
                      [0, 1, 1, 0, 2, 2, 0],
                      [0, 1, 1, 0, 2, 2, 0],
                      [1, 0, 0, 0, 0, 0, 3],
                      [0, 1, 1, 1, 3, 3, 4]])

    flood_fill(image, (0, 0), 5, inplace=True)

    expected = np.array([[5, 5, 5, 5, 5, 5, 5],
                         [5, 1, 1, 5, 2, 2, 5],
                         [5, 1, 1, 5, 2, 2, 5],
                         [1, 5, 5, 5, 5, 5, 3],
                         [5, 1, 1, 1, 3, 3, 4]])

    np.testing.assert_array_equal(image, expected)
Пример #22
0
def test_inplace_float():
    image = np.array([[0, 0, 0, 0, 0, 0, 0],
                      [0, 1, 1, 0, 2, 2, 0],
                      [0, 1, 1, 0, 2, 2, 0],
                      [1, 0, 0, 0, 0, 0, 3],
                      [0, 1, 1, 1, 3, 3, 4]], dtype=np.float32)

    flood_fill(image, (0, 0), 5, inplace=True)

    expected = np.array([[5., 5., 5., 5., 5., 5., 5.],
                         [5., 1., 1., 5., 2., 2., 5.],
                         [5., 1., 1., 5., 2., 2., 5.],
                         [1., 5., 5., 5., 5., 5., 3.],
                         [5., 1., 1., 1., 3., 3., 4.]], dtype=np.float32)

    np.testing.assert_allclose(image, expected)
Пример #23
0
def load_horizontal_mask(ann_d, liver_mask, verbose_curve=True):
    shape = liver_mask.shape
    curve_dict = ann_d['Horizontal']['data']
    l = liver_mask.any(axis=(1, 2))
    liver_start, liver_stop = np.argmax(l), len(l) - np.argmax(l[::-1]) - 1
    curve_start, curve_stop = np.array(sorted(map(int,
                                                  curve_dict.keys())))[[0, -1]]
    curve_dict[str(liver_start)] = curve_dict[str(curve_start)]
    curve_dict[str(liver_stop)] = curve_dict[str(curve_stop)]

    curve_slices = interpolate_dict(curve_dict, shape[0], closed=False)
    mask = []
    for curve_slice, liver_slice in zip(curve_slices, liver_mask):
        m_ = np.zeros_like(liver_slice)
        if not curve_slice.any():
            mask.append(m_)
            continue
        curve_slice = extrapolate_first_and_last_segments_to_border(
            curve_slice, liver_slice.shape)
        m_ = flood_fill(m_ + 2 * plot_curve(curve_slice, liver_slice.shape),
                        (0, 0),
                        new_value=1,
                        connectivity=1) == 1
        # TODO: get zones for all image, not only for a liver
        m_ = (m_ + 1) * liver_slice

        if verbose_curve:
            m_[plot_curve(curve_slice, liver_slice.shape)] = -1

        mask.append(m_)

    return np.stack(mask)
Пример #24
0
def test_neighbors():
    # This test will only pass if the neighbors are exactly correct
    test = np.zeros((5, 7), dtype=np.float64)
    test[:, 3] = 100

    expected = np.array([[0, 0, 0, 255, 0, 0, 0], [0, 0, 0, 255, 0, 0, 0],
                         [0, 0, 0, 255, 0, 0, 0], [0, 0, 0, 255, 0, 0, 0],
                         [0, 0, 0, 255, 0, 0, 0]])
    output = flood_fill(test, (0, 3), 255)

    np.testing.assert_equal(output, expected)

    test[2] = 100
    expected[2] = 255

    output2 = flood_fill(test, (2, 3), 255)

    np.testing.assert_equal(output2, expected)
Пример #25
0
def test_empty_input():
    # Test shortcut
    output = flood_fill(np.empty(0), (), 2)
    assert output.size == 0

    # Boolean output type
    assert flood(np.empty(0), ()).dtype == np.bool

    # Maintain shape, even with zero size present
    assert flood(np.empty((20, 0, 4)), ()).shape == (20, 0, 4)
Пример #26
0
def test_inplace_float_deprecated():
    """This test is deprecated and will be removed in
    version 0.19.0. See #4248.
    """
    image = np.array(
        [[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 2, 2, 0], [0, 1, 1, 0, 2, 2, 0],
         [1, 0, 0, 0, 0, 0, 3], [0, 1, 1, 1, 3, 3, 4]],
        dtype=np.float32)

    with expected_warnings(['The `inplace`']):
        flood_fill(image, (0, 0), 5, inplace=True)

    expected = np.array(
        [[5., 5., 5., 5., 5., 5., 5.], [5., 1., 1., 5., 2., 2., 5.],
         [5., 1., 1., 5., 2., 2., 5.], [1., 5., 5., 5., 5., 5., 3.],
         [5., 1., 1., 1., 3., 3., 4.]],
        dtype=np.float32)

    np.testing.assert_allclose(image, expected)
Пример #27
0
def test_empty_input():
    # Test shortcut
    output = flood_fill(np.empty(0), (), 2)
    assert output.size == 0

    # Boolean output type
    assert flood(np.empty(0), ()).dtype == np.bool

    # Maintain shape, even with zero size present
    assert flood(np.empty((20, 0, 4)), ()).shape == (20, 0, 4)
Пример #28
0
def test_neighbors():
    # This test will only pass if the neighbors are exactly correct
    test = np.zeros((5, 7), dtype=np.float64)
    test[:, 3] = 100

    expected = np.array([[0, 0, 0, 255, 0, 0, 0],
                         [0, 0, 0, 255, 0, 0, 0],
                         [0, 0, 0, 255, 0, 0, 0],
                         [0, 0, 0, 255, 0, 0, 0],
                         [0, 0, 0, 255, 0, 0, 0]])
    output = flood_fill(test, (0, 3), 255)

    np.testing.assert_equal(output, expected)

    test[2] = 100
    expected[2] = 255

    output2 = flood_fill(test, (2, 3), 255)

    np.testing.assert_equal(output2, expected)
Пример #29
0
def test_overrange_tolerance_float():
    max_value = np.finfo(np.float32).max

    image = np.random.uniform(size=(64, 64), low=-1., high=1.).astype(
        np.float32)
    image *= max_value

    expected = np.ones_like(image)
    output = flood_fill(image, (0, 1), 1., tolerance=max_value * 10)

    np.testing.assert_equal(output, expected)
Пример #30
0
def test_overrange_tolerance_float():
    max_value = np.finfo(np.float32).max
    min_value = np.finfo(np.float32).min

    image = np.random.uniform(size=(64, 64), low=-1., high=1.).astype(
        np.float32)
    image *= max_value

    expected = np.ones_like(image)
    output = flood_fill(image, (0, 1), 1., tolerance=max_value * 10)

    np.testing.assert_equal(output, expected)
Пример #31
0
def test_wraparound():
    # If the borders (or neighbors) aren't correctly accounted for, this fails,
    # because the algorithm uses an ravelled array.
    test = np.zeros((5, 7), dtype=np.float64)
    test[:, 3] = 100

    expected = np.array([[-1., -1., -1., 100., 0., 0., 0.],
                         [-1., -1., -1., 100., 0., 0., 0.],
                         [-1., -1., -1., 100., 0., 0., 0.],
                         [-1., -1., -1., 100., 0., 0., 0.],
                         [-1., -1., -1., 100., 0., 0., 0.]])

    np.testing.assert_equal(flood_fill(test, (0, 0), -1), expected)
Пример #32
0
    def __isolate_lung(self, seg):
        """
        :param seg:
        :return:
        """
        cut_seg = np.zeros((seg.shape))
        new_seg1 = np.zeros((seg.shape))
        new_seg1[:, :, :] = 1 - seg[:, :, :]
        new_seg = binary_closing(np.copy(new_seg1), np.ones((3, 3, 3)))
        m_ax = (new_seg.shape[2] * 1) // 2
        cut_seg[:,:,m_ax:] = np.copy(new_seg[:,:,m_ax:])
        cut_seg[:,:,m_ax:] = flood_fill(cut_seg[:,:,m_ax:],(0, 0, 0), 2)
        cut_seg[:, :, m_ax:] = flood_fill(cut_seg[:, :, m_ax:], (
        cut_seg[:, :, m_ax:].shape[0] - 1, cut_seg[:, :, m_ax:].shape[1] - 1, 0), 3)
        new_seg[np.where((cut_seg == 2) | (cut_seg == 3))] = 0
        reg_seg = np.copy(new_seg)
        new_seg[:,:,m_ax:] = self.__choose_largest_co_component(np.copy(reg_seg[:, :, m_ax:]) , 1)
        new_seg = np.array(new_seg, dtype=np.int)
        new_seg[:,:,m_ax:] += self.__choose_largest_co_component(np.copy(reg_seg[:, :, m_ax:]) , 2)
        new_seg[:, :, :m_ax] = 0

        min_sa, min_ca, min_a_a, max_s_a, max_c_a, max_a_a = self.__found_bounding_box(self.aorta_mat)
        new_seg[min_sa: max_s_a,min_ca:max_c_a,min_a_a: max_a_a] = 6
        new_seg = np.array(new_seg, dtype=np.int)
        cut_seg = np.array(cut_seg, dtype=np.int)

        seg_file = nib.Nifti1Image(new_seg, self.ct_file.affine)
        seg_file1 = nib.Nifti1Image(cut_seg, self.ct_file.affine)
        seg_file2 = nib.Nifti1Image(new_seg1, self.ct_file.affine)


        nib.save(seg_file, self.dir_results +
                 self.ct_scan + '_final_lungs_' + LUNG_SEG + NIFTY_END)
        nib.save(seg_file1,  self.dir_results  +
                 self.ct_scan + '_air_and_lung_' + LUNG_SEG + NIFTY_END)
        nib.save(seg_file2, self.dir_results +
                 self.ct_scan + '_raw_' + LUNG_SEG + NIFTY_END)

        return new_seg
Пример #33
0
def test_wraparound():
    # If the borders (or neighbors) aren't correctly accounted for, this fails,
    # because the algorithm uses an ravelled array.
    test = np.zeros((5, 7), dtype=np.float64)
    test[:, 3] = 100

    expected = np.array([[-1., -1., -1., 100., 0., 0., 0.],
                         [-1., -1., -1., 100., 0., 0., 0.],
                         [-1., -1., -1., 100., 0., 0., 0.],
                         [-1., -1., -1., 100., 0., 0., 0.],
                         [-1., -1., -1., 100., 0., 0., 0.]])

    np.testing.assert_equal(flood_fill(test, (0, 0), -1), expected)
Пример #34
0
def test_basic_nd():
    for dimension in (3, 4, 5):
        shape = (5,) * dimension
        hypercube = np.zeros(shape)
        slice_mid = tuple(slice(1, -1, None) for dim in range(dimension))
        hypercube[slice_mid] = 1  # sum is 3**dimension
        filled = flood_fill(hypercube, (2,)*dimension, 2)

        # Test that the middle sum is correct
        assert filled.sum() == 3**dimension * 2

        # Test that the entire array is as expected
        np.testing.assert_equal(
            filled, np.pad(np.ones((3,)*dimension) * 2, 1, 'constant'))
Пример #35
0
def test_basic_nd():
    for dimension in (3, 4, 5):
        shape = (5, ) * dimension
        hypercube = np.zeros(shape)
        slice_mid = tuple(slice(1, -1, None) for dim in range(dimension))
        hypercube[slice_mid] = 1  # sum is 3**dimension
        filled = flood_fill(hypercube, (2, ) * dimension, 2)

        # Test that the middle sum is correct
        assert filled.sum() == 3**dimension * 2

        # Test that the entire array is as expected
        np.testing.assert_equal(
            filled, np.pad(np.ones((3, ) * dimension) * 2, 1, 'constant'))
Пример #36
0
def test_negative_indexing_seed_point():
    image = np.array(
        [[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 2, 2, 0], [0, 1, 1, 0, 2, 2, 0],
         [1, 0, 0, 0, 0, 0, 3], [0, 1, 1, 1, 3, 3, 4]],
        dtype=np.float32)

    expected = np.array(
        [[5., 5., 5., 5., 5., 5., 5.], [5., 1., 1., 5., 2., 2., 5.],
         [5., 1., 1., 5., 2., 2., 5.], [1., 5., 5., 5., 5., 5., 3.],
         [5., 1., 1., 1., 3., 3., 4.]],
        dtype=np.float32)

    image = flood_fill(image, (0, -1), 5)

    np.testing.assert_allclose(image, expected)
Пример #37
0
 def flood_fill(self, event):
     """
     Fills a contour selected by the middle mouse button with the mask.
     """
     if event.widget is self.image_label:
         for i in range(3):
             self.mask[:, :, i] = flood_fill(self.mask[:, :, i],
                                             seed_point=(event.y, event.x),
                                             new_value=255,
                                             tolerance=1)
             self.display_image[:, :,
                                i] = np.where(self.mask[:, :, i] == 255,
                                              255, self.display_image[:, :,
                                                                      i])
         self.update_image()
def office_has_path(office):
    desks = np.copy(office.desks)
    start_col = office.start_col
    start_row = desks.shape[0] - 1

    # When you stand up, your desk becomes empty
    desks[start_row, start_col] = DESK_EMPTY

    # draw a path everywhere you can reach
    desks_with_path = flood_fill(desks, (start_row, start_col), DESK_PATH)

    # look for a path to any desk in the exit row
    path_found = any(DESK_PATH == desk
                     for desk in desks_with_path[DESKROW_EXIT])

    return path_found
Пример #39
0
    def fill_holes(self, origin='center', **kwargs):
        """fill_holes

        https://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.ndimage.morphology.binary_fill_holes.html

        Args:
            structure (_np.array, optional):
                [description]. Defaults to _np.ones((3,3)).
        """
        if isinstance(origin, str):
            if origin.lower() == 'center':
                h, w = self.shape
                origin = (h // 2, w // 2)

        image = skm.flood_fill(self, origin, 1, **kwargs)
        return image
Пример #40
0
    def action_fill_hole(self, label, frame, x_location, y_location):
        '''
        fill a "hole" in a cell annotation with the cell label. Doesn't check
        if annotation at (y,x) is zero (hole to fill) because that logic is handled in
        javascript. Just takes the click location, scales it to match the actual annotation
        size, then fills the hole with label (using skimage flood_fill). connectivity = 1
        prevents hole fill from spilling out into background in some cases
        '''
        # rescale click location -> corresponding location in annotation array
        hole_fill_seed = (y_location // self.scale_factor, x_location // self.scale_factor)
        # fill hole with label
        img_ann = self.tracked[frame,:,:,0]
        filled_img_ann = flood_fill(img_ann, hole_fill_seed, label, connectivity = 1)
        self.tracked[frame,:,:,0] = filled_img_ann

        self.frames_changed = True
Пример #41
0
    def action_flood_contiguous(self, label, frame, x_location, y_location):
        '''
        flood fill a cell with a unique new label; alternative to watershed
        for fixing duplicate label issue if cells are not touching
        '''
        img_ann = self.tracked[frame,:,:,0]
        old_label = label
        new_label = max(self.tracks) + 1

        in_original = np.any(np.isin(img_ann, old_label))

        filled_img_ann = flood_fill(img_ann, (int(y_location/self.scale_factor), int(x_location/self.scale_factor)), new_label)
        self.tracked[frame,:,:,0] = filled_img_ann

        in_modified = np.any(np.isin(filled_img_ann, old_label))

        # update cell info dicts since labels are changing
        self.add_cell_info(add_label=new_label, frame = frame)

        if in_original and not in_modified:
            self.del_cell_info(del_label = old_label, frame = frame)
Пример #42
0
def test_float16():
    image = np.array([9., 0.1, 42], dtype=np.float16)
    with raises(TypeError, match="dtype of `image` is float16"):
        flood_fill(image, 0, 1)