Exemplo n.º 1
0
    def test_tree_fusion3(self):
        im1 = np.asarray(
            (0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 2, 1, 1, 1, 3, 3, 3, 2, 1, 1, 1, 3,
             3, 3, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0),
            dtype=np.float32)

        im2 = np.asarray(
            (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 2, 0, 0,
             1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
            dtype=np.float32)

        g = hg.get_4_adjacency_implicit_graph((6, 7))

        t1, _ = hg.component_tree_max_tree(g, im1)
        t2, _ = hg.component_tree_max_tree(g, im2)

        res = hg.tree_fusion_depth_map((t1, t2))

        expected = np.asarray(
            (0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 2, 1, 1, 1, 3, 4, 3, 2, 2, 3, 1, 3,
             3, 3, 2, 2, 3, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0),
            dtype=np.float32)

        diff = expected - res
        self.assertTrue(np.all(diff == diff[0]))
Exemplo n.º 2
0
def component_tree_tree_of_shapes_image2d(image,
                                          padding='mean',
                                          original_size=True,
                                          exterior_vertex=0):
    """
    Tree of shapes of a 2d image.

    The Tree of Shapes was described in [1]_.
    The algorithm used in this implementation was first described in [2]_.

    The tree is computed in the interpolated multivalued Khalimsky space to provide a continuous and autodual representation of
    input image.

    Possible values of `padding` are `'none'`, `'mean'`, and `'zero'`.
    If `padding` is different from 'none', an extra border of pixels is added to the input image before
    anything else. This will ensure the existence of a shape encompassing all the shapes inside the input image
    (if exterior_vertex is inside the extra border): this shape will be the root of the tree.
    The padding value can be:

      - 0 if :attr:`padding` is equal to ``"zero"``;
      - the mean value of the boundary pixels of the input image if :attr:`padding` is equal to ``"mean"``.

    If :attr:`original_size` is ``True``, all the nodes corresponding to pixels not belonging to the input image
    are removed (except for the root node).
    If :attr:`original_size` is ``False``, the returned tree is the tree constructed in the interpolated/padded space.
    In practice if the size of the input image is :math:`(h, w)`, the leaves of the returned tree will correspond to an
    image of size:

      - :math:`(h, w)` if :attr:`original_size` is ``True``;
      - :math:`(h * 2 - 1, w * 2 - 1)` is :attr:`original_size` is ``False`` and padding is ``"none"``; and
      - :math:`((h + 2) * 2 - 1, (w + 2) * 2 - 1)` otherwise.

    :attr:`Exterior_vertex` defines the linear coordinates of the pixel corresponding to the exterior
    (interior and exterior of a shape is defined with respect to this point). The coordinate of this point must be
    given in the padded/interpolated space.

    .. [1] Pa. Monasse, and F. Guichard, "Fast computation of a contrast-invariant image representation," \
    Image Processing, IEEE Transactions on, vol.9, no.5, pp.860-872, May 2000

    .. [2] Th. Géraud, E. Carlinet, S. Crozet, and L. Najman, "A Quasi-linear Algorithm to Compute the Tree \
    of Shapes of nD Images", ISMM 2013.

    :param image: must be a 2d array
    :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 exterior_vertex: linear coordinate of the exterior point
    :return: a tree (Concept :class:`~higra.CptHierarchy`) and its node altitudes
    """

    res = hg.cpp._component_tree_tree_of_shapes_image2d(
        image, padding, original_size, exterior_vertex)
    tree = res.tree()
    altitudes = res.altitudes()

    g = hg.get_4_adjacency_implicit_graph(image.shape)
    hg.CptHierarchy.link(tree, g)

    return tree, altitudes
Exemplo n.º 3
0
    def test_create_graph(self):
        shape = (2, 3)
        nl = ((-1, 0), (0, -1), (0, 1), (1, 0))
        g1 = hg.RegularGraph2d(hg.EmbeddingGrid2d(shape), nl)

        g2 = hg.get_4_adjacency_implicit_graph(shape)
        g3 = hg.get_8_adjacency_implicit_graph(shape)

        for g in (g1, g2, g3):
            self.assertTrue(g.num_vertices() == 6)
Exemplo n.º 4
0
    def test_reconstruct_leaf_data_component_tree_default(self):
        g = hg.get_4_adjacency_implicit_graph((1, 6))
        vertex_values = np.asarray((1, 5, 4, 3, 3, 6), dtype=np.int32)
        tree, altitudes = hg.component_tree_max_tree(g, vertex_values)

        area = hg.attribute_area(tree)
        output = hg.reconstruct_leaf_data(tree, area)
        ref = np.asarray((6, 1, 2, 5, 5, 1), dtype=np.int32)

        self.assertTrue(np.all(ref == output))
Exemplo n.º 5
0
    def test_reconstruct_leaf_data_component_tree(self):
        g = hg.get_4_adjacency_implicit_graph((1, 6))
        vertex_values = np.asarray((1, 5, 4, 3, 3, 6), dtype=np.int32)
        tree, altitudes = hg.component_tree_max_tree(g, vertex_values)

        condition = np.asarray((True, False, True, False, True, True, False, True, False, True, False), np.bool_)

        output = hg.reconstruct_leaf_data(tree, altitudes, condition)
        ref = np.asarray((1, 4, 4, 1, 1, 6), dtype=np.int32)

        self.assertTrue(np.all(ref == output))
Exemplo n.º 6
0
    def test_tree_attribute_extrema2(self):
        graph = hg.get_4_adjacency_implicit_graph((4, 4))
        vertex_weights = np.asarray(
            (0, 1, 4, 4, 7, 5, 6, 8, 2, 3, 4, 1, 9, 8, 6, 7))

        tree, altitudes = hg.component_tree_max_tree(graph, vertex_weights)

        extrema = hg.attribute_extrema(tree, altitudes)
        expected_extrema = np.asarray(
            (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0,
             0, 0, 0, 0, 0, 0, 0))
        self.assertTrue(np.all(expected_extrema == extrema))
Exemplo n.º 7
0
    def test_out_edge_iterator4(self):
        shape = (2, 3)
        g = hg.get_4_adjacency_implicit_graph(shape)

        ref = [[(0, 1), (0, 3)], [(1, 0), (1, 2), (1, 4)], [(2, 1), (2, 5)],
               [(3, 0), (3, 4)], [(4, 1), (4, 3), (4, 5)], [(5, 2), (5, 4)]]

        for v in g.vertices():
            res = []
            for e in g.out_edges(v):
                res.append((g.source(e), g.target(e)))

            self.assertTrue(res == ref[v])
Exemplo n.º 8
0
    def test_vertices_iterator(self):
        shape = (2, 3)
        g1 = hg.get_4_adjacency_implicit_graph(shape)
        g2 = hg.get_8_adjacency_implicit_graph(shape)

        vref = [0, 1, 2, 3, 4, 5];

        for g in (g1, g2):
            vtest = [];

            for v in g.vertices():
                vtest.append(v)

            self.assertTrue(vtest == vref)
Exemplo n.º 9
0
    def test_as_explicit_graph(self):
        shape = (2, 3)
        g_imp = hg.get_4_adjacency_implicit_graph(shape)

        g_exp = g_imp.as_explicit_graph()

        self.assertTrue(
            TestRegularGraph.graph_implicit_explicit_equal(g_imp, g_exp))

        g_imp = hg.get_8_adjacency_implicit_graph(shape)

        g_exp = g_imp.as_explicit_graph()

        self.assertTrue(
            TestRegularGraph.graph_implicit_explicit_equal(g_imp, g_exp))
Exemplo n.º 10
0
    def test_component_tree_max_tree(self):
        graph = hg.get_4_adjacency_implicit_graph((4, 4))
        vertex_weights = np.asarray(
            ((0, 1, 4, 4), (7, 5, 6, 8), (2, 3, 4, 1), (9, 8, 6, 7)),
            dtype=np.float64)
        tree, altitudes = hg.component_tree_max_tree(graph, vertex_weights)

        expected_parents = np.asarray(
            (28, 27, 24, 24, 20, 23, 22, 18, 26, 25, 24, 27, 16, 17, 21, 19,
             17, 21, 22, 21, 23, 24, 23, 24, 25, 26, 27, 28, 28), np.int64)
        expected_altitudes = np.asarray(
            (0., 1., 4., 4., 7., 5., 6., 8., 2., 3., 4., 1., 9., 8., 6., 7.,
             9., 8., 8., 7., 7., 6., 6., 5., 4., 3., 2., 1., 0.), np.float64)

        self.assertTrue(np.all(expected_parents == tree.parents()))
        self.assertTrue(np.allclose(expected_altitudes, altitudes))
Exemplo n.º 11
0
    def test_simplify_tree_propagate_category(self):
        g = hg.get_4_adjacency_implicit_graph((1, 6))
        vertex_values = np.asarray((1, 5, 4, 3, 3, 6), dtype=np.int32)
        tree, altitudes = hg.component_tree_max_tree(g, vertex_values)

        condition = np.asarray((False, False, False, False, False, False,
                                False, True, False, True, False), np.bool)

        new_tree, node_map = hg.simplify_tree(tree, condition)

        self.assertTrue(
            np.all(new_tree.parents() == (8, 7, 7, 8, 8, 6, 8, 8, 8)))
        self.assertTrue(np.all(node_map == (0, 1, 2, 3, 4, 5, 6, 8, 10)))
        self.assertTrue(new_tree.category() == hg.TreeCategory.ComponentTree)

        rec = hg.reconstruct_leaf_data(new_tree, altitudes[node_map])
        self.assertTrue(np.all(rec == (1, 4, 4, 1, 1, 6)))
Exemplo n.º 12
0
    def test_create_graph(self):
        shape = (2, 3)
        nl = ((-1, 0), (0, -1), (0, 1), (1, 0))
        g1 = hg.RegularGraph2d(hg.EmbeddingGrid2d(shape), nl)

        g2 = hg.get_4_adjacency_implicit_graph(shape)
        g3 = hg.get_8_adjacency_implicit_graph(shape)

        for g in (g1, g2, g3):
            self.assertTrue(g.num_vertices() == 6)

        self.assertTrue(np.all(g1.shape() == shape))
        self.assertTrue(np.all(g1.neighbour_list() == nl))

        g4 = hg.RegularGraph2d(g1.shape(), g1.neighbour_list())
        self.assertTrue(np.all(g4.shape() == shape))
        self.assertTrue(np.all(g4.neighbour_list() == nl))
Exemplo n.º 13
0
    def test_area_filter_max_tree(self):
        graph = hg.get_4_adjacency_implicit_graph((5, 5))
        vertex_weights = np.asarray(
            ((-5, 2, 2, 5, 5), (-4, 2, 2, 6, 5), (3, 3, 3, 3, 3),
             (-2, -2, -2, 9, 7), (-1, 0, -2, 8, 9)),
            dtype=np.float64)
        tree, altitudes = hg.component_tree_max_tree(graph, vertex_weights)
        area = hg.attribute_area(tree)

        filtered_weights = hg.reconstruct_leaf_data(tree, altitudes, area <= 4)

        expected_filtered_weights = \
            np.asarray(((-5, 2, 2, 3, 3),
                        (-4, 2, 2, 3, 3),
                        (3, 3, 3, 3, 3),
                        (-2, -2, -2, 3, 3),
                        (-2, -2, -2, 3, 3)), dtype=np.float64)

        self.assertTrue(np.all(filtered_weights == expected_filtered_weights))
Exemplo n.º 14
0
    def test_attribute_extinction_value2(self):
        graph = hg.get_4_adjacency_implicit_graph((4, 4))
        vertex_weights = np.asarray(
            (0, 1, 4, 4, 7, 5, 6, 8, 2, 3, 4, 1, 9, 8, 6, 7))

        tree, altitudes = hg.component_tree_max_tree(graph, vertex_weights)
        area = hg.attribute_area(tree)

        expected_ext = np.asarray(
            (0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 16, 0, 0, 1, 16, 16, 4, 1, 1,
             16, 4, 4, 16, 16, 16, 16, 16))

        ext = hg.attribute_extinction_value(tree, altitudes, area)
        self.assertTrue(np.all(expected_ext == ext))

        ext = hg.attribute_extinction_value(tree, altitudes, area, False)
        self.assertTrue(np.all(expected_ext == ext))

        ext = hg.attribute_extinction_value(tree, altitudes, area,
                                            "decreasing")
        self.assertTrue(np.all(expected_ext == ext))
Exemplo n.º 15
0
    def test_moment_of_inertia(self):
        """
        The test image is a binary image of 5x15 pixels:
        
        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
        0 0 1 0 0 1 0 0 0 0 0 1 1 1 0
        0 1 1 1 0 1 0 1 1 1 0 1 1 1 0
        0 0 1 0 0 1 0 0 0 0 0 1 1 1 0
        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
        
        The max-tree of this image is composed of five non-leaf nodes: 
        the root and the four maxima (a cross, a vertical line, a horizontal line and a square)
        Using the formula given in https://en.wikipedia.org/wiki/Image_moment, the moment of inertia of each shape is:
          - Cross: 0.16
          - Square: 0.1481
          - Vertical and horizontal lines: 0.2222
          - Rectangle (root): 0.2756
        The moment of inertia of the leaf nodes are set to 0.0
        
       
        """
        graph = hg.get_4_adjacency_implicit_graph((5, 15))
        vertex_weights = np.asarray(
            [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0],
             [0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0],
             [0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

        tree, altitudes = hg.component_tree_max_tree(graph, vertex_weights)
        res = hg.attribute_moment_of_inertia(tree)
        ref = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1481, 0.2222, 0.16,
               0.2222, 0.2756)
        self.assertTrue(np.allclose(res, ref, atol=0.0001))
Exemplo n.º 16
0
 def test_argument_helper_accept_RegularGraph2d(self):
     g = hg.get_4_adjacency_implicit_graph((2, 3))
     self.assertTrue(accept_RegularGraph2d(g) == 2)
     self.assertRaises(MyException, accept_RegularGraph2d, (4, 5), (2, 3))
     hg.clear_all_attributes()
Exemplo n.º 17
0
 def test_dynamic_attributes(self):
     shape = (2, 3)
     g = hg.get_4_adjacency_implicit_graph(shape)
     g.new_attribute = 42
     self.assertTrue(g.new_attribute == 42)