Esempio n. 1
0
    def test_tree_of_shapes_self_dual(self):
        np.random.seed(42)
        image = np.random.rand(25, 38)
        neg_image = -1 * image

        tree1, altitudes1 = hg.component_tree_tree_of_shapes_image2d(image)
        tree2, altitudes2 = hg.component_tree_tree_of_shapes_image2d(neg_image)

        self.assertTrue(hg.test_tree_isomorphism(tree1, tree2))
Esempio n. 2
0
    def test_tree_of_shapes_no_padding(self):
        image = np.asarray(
            ((1, 1, 1, 1, 1, 1), (1, 0, 0, 3, 3, 1), (1, 0, 1, 1, 3, 1),
             (1, 0, 0, 3, 3, 1), (1, 1, 1, 1, 1, 1)),
            dtype=np.int8)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(
            image, 'none', False)
        ref_parents = np.asarray(
            (101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
             101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 100, 100,
             100, 101, 99, 99, 99, 101, 101, 101, 101, 100, 101, 101, 101, 101,
             101, 99, 101, 101, 101, 101, 100, 101, 101, 101, 101, 101, 99,
             101, 101, 101, 101, 100, 101, 101, 101, 101, 101, 99, 101, 101,
             101, 101, 100, 100, 100, 101, 99, 99, 99, 101, 101, 101, 101, 101,
             101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
             101, 101, 101, 101, 101, 101, 101, 101, 101),
            dtype=np.int64)

        ref_altitudes = np.asarray(
            (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
             1, 1, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 1,
             1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 1,
             1, 1, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
             1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 1),
            dtype=np.int8)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.all(altitudes == ref_altitudes))
Esempio n. 3
0
    def test_tree_of_shapes_padding_0(self):
        image = np.asarray(((1, 1, 1),
                            (1, -2, 3)), dtype=np.int32)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(image, 'zero', False)
        ref_parents = np.asarray((66, 66, 66, 66, 66, 66, 66, 66, 66,
                                  66, 66, 66, 66, 66, 66, 66, 66, 66,
                                  66, 66, 65, 65, 65, 65, 65, 66, 66,
                                  66, 66, 65, 66, 66, 66, 65, 66, 66,
                                  66, 66, 65, 66, 63, 66, 64, 66, 66,
                                  66, 66, 66, 66, 66, 66, 66, 66, 66,
                                  66, 66, 66, 66, 66, 66, 66, 66, 66,
                                  66, 65, 66, 66), dtype=np.int64)

        ref_altitudes = np.asarray((0, 0, 0, 0, 0, 0, 0, 0, 0,
                                    0, 0, 0, 0, 0, 0, 0, 0, 0,
                                    0, 0, 1, 1, 1, 1, 1, 0, 0,
                                    0, 0, 1, 0, 0, 0, 1, 0, 0,
                                    0, 0, 1, 0, -2, 0, 3, 0, 0,
                                    0, 0, 0, 0, 0, 0, 0, 0, 0,
                                    0, 0, 0, 0, 0, 0, 0, 0, 0,
                                    -2, 3, 1, 0), dtype=np.int32)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.all(altitudes == ref_altitudes))

        leaf_graph = hg.CptHierarchy.get_leaf_graph(tree)
        res_shape = hg.CptGridGraph.get_shape(leaf_graph)
        self.assertTrue(len(res_shape) == 2)
        self.assertTrue(res_shape[0] * res_shape[1] == tree.num_leaves())
        self.assertTrue(res_shape[0] == (image.shape[0] + 2) * 2 - 1)
        self.assertTrue(res_shape[1] == (image.shape[1] + 2) * 2 - 1)
Esempio n. 4
0
def patches_batch_tos_area_p(batch_image, i, j, l):
    tree, altitudes = hg.component_tree_tree_of_shapes_image2d(
        batch_image[i, :, :, 0])
    area = hg.attribute_area(tree)
    batch_image[i, :, :,
                j + 1] = hg.reconstruct_leaf_data(tree, altitudes, area < l)
    return batch_image[i, :, :, j + 1]
Esempio n. 5
0
    def test_tree_of_shapes_no_padding_original_space(self):
        image = np.asarray(((1, 1, 1, 1, 1, 1),
                            (1, 0, 0, 3, 3, 1),
                            (1, 0, 1, 1, 3, 1),
                            (1, 0, 0, 3, 3, 1),
                            (1, 1, 1, 1, 1, 1)), dtype=np.float64)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(image, 'none', True)
        ref_parents = np.asarray((32, 32, 32, 32, 32, 32,
                                  32, 30, 30, 31, 31, 32,
                                  32, 30, 32, 32, 31, 32,
                                  32, 30, 30, 31, 31, 32,
                                  32, 32, 32, 32, 32, 32,
                                  32, 32, 32), dtype=np.int64)

        ref_altitudes = np.asarray((1, 1, 1, 1, 1, 1,
                                    1, 0, 0, 3, 3, 1,
                                    1, 0, 1, 1, 3, 1,
                                    1, 0, 0, 3, 3, 1,
                                    1, 1, 1, 1, 1, 1,
                                    0, 3, 1), dtype=np.float64)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.all(altitudes == ref_altitudes))

        leaf_graph = hg.CptHierarchy.get_leaf_graph(tree)
        res_shape = hg.CptGridGraph.get_shape(leaf_graph)
        self.assertTrue(len(res_shape) == 2)
        self.assertTrue(res_shape[0] * res_shape[1] == tree.num_leaves())
        self.assertTrue(res_shape[0] == image.shape[0])
        self.assertTrue(res_shape[1] == image.shape[1])
Esempio n. 6
0
def patches_batch_tos_area(batch_image, batch_size, lambdas):
    for i in range(batch_size):
        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(
            batch_image[i, :, :, 0])
        area = hg.attribute_area(tree)

        for j in range(len(lambdas)):
            batch_image[i, :, :, j + 1] = hg.reconstruct_leaf_data(
                tree, altitudes, area < lambdas[j])

    return batch_image
Esempio n. 7
0
    def test_component_tree_multivariate_tree_of_shapes_image2d_sanity(self):
        image = np.asarray(((1, 1),
                            (1, -2),
                            (1, 7)), dtype=np.float64)

        tree, _ = hg.component_tree_tree_of_shapes_image2d(image, 'mean')

        image3d = np.dstack((image, image, image))
        tree2 = hg.component_tree_multivariate_tree_of_shapes_image2d(image3d, 'mean')

        self.assertTrue(hg.test_tree_isomorphism(tree, tree2))
Esempio n. 8
0
    def test_tree_of_shapes_padding_0_original_space(self):
        image = np.asarray(((1, 1, 1), (1, -2, 3)), dtype=np.int32)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(
            image, 'zero', True)
        ref_parents = np.asarray((8, 8, 8, 8, 6, 7, 9, 8, 9, 9),
                                 dtype=np.int64)

        ref_altitudes = np.asarray((1, 1, 1, 1, -2, 3, -2, 3, 1, 0),
                                   dtype=np.int32)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.all(altitudes == ref_altitudes))
Esempio n. 9
0
    def test_tree_of_shapes_padding_mean_original_space(self):
        image = np.asarray(((1, 1), (1, -2), (1, 7)), dtype=np.float64)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(
            image, 'mean', True)
        ref_parents = np.asarray((8, 8, 8, 7, 8, 6, 9, 8, 9, 9),
                                 dtype=np.int64)

        ref_altitudes = np.asarray((1., 1., 1., -2., 1., 7., 7., -2., 1., 1.5),
                                   dtype=np.float64)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.allclose(altitudes, ref_altitudes))
Esempio n. 10
0
    def test_contour_length_tree_of_shapes(self):

        image = np.asarray(
            ((0, 0, 0, 0), (0, -2, 2, 0), (0, -1, 1, 0), (0, 0, 0, 0)))

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(image)

        res = hg.attribute_contour_length(tree)

        ref = np.asarray(
            (4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 16),
            dtype=np.float64)

        self.assertTrue(np.all(res == ref))
Esempio n. 11
0
    def test_tree_of_shapes_no_padding_original_space(self):
        image = np.asarray(
            ((1, 1, 1, 1, 1, 1), (1, 0, 0, 3, 3, 1), (1, 0, 1, 1, 3, 1),
             (1, 0, 0, 3, 3, 1), (1, 1, 1, 1, 1, 1)),
            dtype=np.float64)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(
            image, 'none', True)
        ref_parents = np.asarray((32, 32, 32, 32, 32, 32, 32, 31, 31, 30, 30,
                                  32, 32, 31, 32, 32, 30, 32, 32, 31, 31, 30,
                                  30, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32),
                                 dtype=np.int64)

        ref_altitudes = np.asarray(
            (1, 1, 1, 1, 1, 1, 1, 0, 0, 3, 3, 1, 1, 0, 1, 1, 3, 1, 1, 0, 0, 3,
             3, 1, 1, 1, 1, 1, 1, 1, 3, 0, 1),
            dtype=np.float64)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.all(altitudes == ref_altitudes))
Esempio n. 12
0
    def test_tree_of_shapes_no_immersion_no_padding_no_original_space(self):
        image = np.asarray(((1, 1, 1, 1, 1),
                            (1, 0, 1, 2, 1),
                            (1, 1, 1, 1, 1)), dtype=np.float64)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(image, 'none', original_size=False, immersion=False)
        ref_parents = np.asarray((17, 17, 17, 17, 17,
                                  17, 16, 17, 15, 17,
                                  17, 17, 17, 17, 17, 17, 17, 17), dtype=np.int64)

        ref_altitudes = np.asarray((1, 1, 1, 1, 1,
                                    1, 0, 1, 2, 1,
                                    1, 1, 1, 1, 1, 2, 0, 1), dtype=np.float64)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.allclose(altitudes, ref_altitudes))

        g = hg.CptHierarchy.get_leaf_graph(tree)
        s = hg.CptGridGraph.get_shape(g)
        self.assertTrue(s[0] * s[1] == tree.num_leaves())
Esempio n. 13
0
    def test_tree_of_shapes_padding_0(self):
        image = np.asarray(((1, 1, 1), (1, -2, 3)), dtype=np.int32)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(
            image, 'zero', False)
        ref_parents = np.asarray(
            (66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
             66, 66, 66, 66, 65, 65, 65, 65, 65, 66, 66, 66, 66, 65, 66, 66,
             66, 65, 66, 66, 66, 66, 65, 66, 63, 66, 64, 66, 66, 66, 66, 66,
             66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
             65, 66, 66),
            dtype=np.int64)

        ref_altitudes = np.asarray(
            (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
             1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -2, 0, 3, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 3, 1,
             0),
            dtype=np.int32)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.all(altitudes == ref_altitudes))
Esempio n. 14
0
    def test_tree_of_shapes_padding_0_original_space(self):
        image = np.asarray(((1, 1, 1),
                            (1, -2, 3)), dtype=np.int32)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(image, 'zero', True)
        ref_parents = np.asarray((7, 7, 7,
                                  7, 8, 6,
                                  7, 9, 9, 9), dtype=np.int64)

        ref_altitudes = np.asarray((1, 1, 1,
                                    1, -2, 3,
                                    3, 1, -2, 0), dtype=np.int32)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.all(altitudes == ref_altitudes))

        leaf_graph = hg.CptHierarchy.get_leaf_graph(tree)
        res_shape = hg.CptGridGraph.get_shape(leaf_graph)
        self.assertTrue(len(res_shape) == 2)
        self.assertTrue(res_shape[0] * res_shape[1] == tree.num_leaves())
        self.assertTrue(res_shape[0] == image.shape[0])
        self.assertTrue(res_shape[1] == image.shape[1])
Esempio n. 15
0
    def test_tree_of_shapes_no_padding(self):
        image = np.asarray(((1, 1, 1, 1, 1, 1),
                            (1, 0, 0, 3, 3, 1),
                            (1, 0, 1, 1, 3, 1),
                            (1, 0, 0, 3, 3, 1),
                            (1, 1, 1, 1, 1, 1)), dtype=np.int8)

        tree, altitudes = hg.component_tree_tree_of_shapes_image2d(image, 'none', False)
        ref_parents = np.asarray((101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
                                  101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
                                  101, 101, 100, 100, 100, 101, 99, 99, 99, 101, 101,
                                  101, 101, 100, 101, 101, 101, 101, 101, 99, 101, 101,
                                  101, 101, 100, 101, 101, 101, 101, 101, 99, 101, 101,
                                  101, 101, 100, 101, 101, 101, 101, 101, 99, 101, 101,
                                  101, 101, 100, 100, 100, 101, 99, 99, 99, 101, 101,
                                  101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
                                  101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
                                  101, 101, 101), dtype=np.int64)

        ref_altitudes = np.asarray((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                                    1, 1, 0, 0, 0, 1, 3, 3, 3, 1, 1,
                                    1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 1,
                                    1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 1,
                                    1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 1,
                                    1, 1, 0, 0, 0, 1, 3, 3, 3, 1, 1,
                                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                                    3, 0, 1), dtype=np.int8)
        self.assertTrue(np.all(tree.parents() == ref_parents))
        self.assertTrue(np.all(altitudes == ref_altitudes))

        leaf_graph = hg.CptHierarchy.get_leaf_graph(tree)
        res_shape = hg.CptGridGraph.get_shape(leaf_graph)
        self.assertTrue(len(res_shape) == 2)
        self.assertTrue(res_shape[0] * res_shape[1] == tree.num_leaves())
        self.assertTrue(res_shape[0] == image.shape[0] * 2 - 1)
        self.assertTrue(res_shape[1] == image.shape[1] * 2 - 1)
Esempio n. 16
0
def component_tree_multivariate_tree_of_shapes_image2d(image,
                                                       padding='mean',
                                                       original_size=True,
                                                       immersion=True):
    """
    Multivariate tree of shapes for a 2d multi-band image. This tree is defined as a fusion of the marginal
    trees of shapes. The method is described in:

        E. Carlinet.
        `A Tree of shapes for multivariate images <https://pastel.archives-ouvertes.fr/tel-01280131/file/TH2015PESC1118.pdf>`_.
        PhD Thesis, Université Paris-Est, 2015.

    The input :attr:`image` must be a 3d array of shape :math:`(height, width, channel)`.

    Note that the constructed hierarchy doesn't have natural altitudes associated to its node: as a node is generally
    a fusion of several marginal nodes, we can't associate a single canonical value from the original image to this node.

    The parameters :attr:`padding`, :attr:`original_size`, and :attr:`immersion` are forwarded to the function
    :func:`~higra.component_tree_tree_of_shapes_image2d`: please look at this function documentation for more details.

    :Complexity:

    The worst case runtime complexity of this method is :math:`\mathcal{O}(N^2D^2)` with :math:`N` the number of pixels
    and :math:`D` the number of bands. If the image pixel values are quantized on :math:`K<<N` different values
    (eg. with a color image in :math:`[0..255]^D`), then the worst case runtime complexity can be tightened to
    :math:`\mathcal{O}(NKD^2)`.

    :See:

    This function relies on :func:`~higra.tree_fusion_depth_map` to compute the fusion of the marinal trees.

    :param image: input *color* 2d image
    :param padding: possible values are `'none'`, `'zero'`, and `'mean'` (default = `'mean'`)
    :param original_size: remove all nodes corresponding to interpolated/padded pixels (default = `True`)
    :param immersion: performs a plain map continuous immersion fo the original image (default = `True`)
    :return: a tree (Concept :class:`~higra.CptHierarchy`)
    """
    assert len(
        image.shape
    ) == 3, "This multivariate tree of shapes implementation only supports multichannel 2d images."

    ndim = image.shape[2]

    trees = tuple(
        hg.component_tree_tree_of_shapes_image2d(
            image[:, :,
                  k], padding, original_size=False, immersion=immersion)[0]
        for k in range(ndim))
    g = hg.CptHierarchy.get_leaf_graph(trees[0])
    shape = hg.CptGridGraph.get_shape(g)

    depth_map = hg.tree_fusion_depth_map(trees)

    tree, altitudes = hg.component_tree_tree_of_shapes_image2d(
        np.reshape(depth_map, shape),
        padding="none",
        original_size=False,
        immersion=False)

    if original_size and (immersion or padding != "none"):
        deleted_vertices = np.ones((tree.num_leaves(), ), dtype=np.bool)
        deleted = np.reshape(deleted_vertices, shape)

        if immersion:
            if padding != "none":
                deleted[2:-2:2, 2:-2:2] = False
            else:
                deleted[0::2, 0::2] = False
        else:
            if padding != "none":
                deleted[1:-1, 1::-1] = False

        all_deleted = hg.accumulate_sequential(tree, deleted_vertices,
                                               hg.Accumulators.min)
        shape = (image.shape[0], image.shape[1])
    else:
        all_deleted = np.zeros((tree.num_vertices(), ), dtype=np.bool)

    holes = altitudes < altitudes[tree.parents()]

    all_deleted = np.logical_or(all_deleted, holes)

    tree, _ = hg.simplify_tree(tree, all_deleted, process_leaves=True)

    g = hg.get_4_adjacency_graph(shape)
    hg.CptHierarchy.link(tree, g)

    return tree