Пример #1
0
def attribute_contour_strength(tree, edge_weights, vertex_perimeter=None, edge_length=None, leaf_graph=None):
    """
    Strength of the contour of each node of the given tree. The strength of the contour of a node is defined as the
    mean edge weights on the contour.

    :param tree: input tree (Concept :class:`~higra.CptHierarchy`)
    :param edge_weights: edge_weights of the leaf graph
    :param vertex_perimeter: perimeter of each vertex of the leaf graph (provided by :func:`~higra.attribute_vertex_perimeter` on `leaf_graph`)
    :param edge_length: length of each edge of the leaf graph (provided by :func:`~higra.attribute_edge_length` on `leaf_graph`)
    :param leaf_graph: (deduced from :class:`~higra.CptHierarchy`)
    :return: a 1d array
    """

    if vertex_perimeter is None:
        vertex_perimeter = hg.attribute_vertex_perimeter(leaf_graph)

    if edge_length is None:
        edge_length = hg.attribute_edge_length(leaf_graph)

    perimeter = attribute_contour_length(tree, vertex_perimeter, edge_length, leaf_graph)

    # perimeter of the root may be null
    if np.isclose(perimeter[-1], 0):
        perimeter[-1] = 1

    if hg.CptRegionAdjacencyGraph.validate(leaf_graph):
        edge_weights = hg.rag_accumulate_on_edges(leaf_graph, hg.Accumulators.sum, edge_weights)

    vertex_weights_sum = hg.accumulate_graph_edges(leaf_graph, edge_weights, hg.Accumulators.sum)
    edge_weights_sum = attribute_contour_length(tree, vertex_weights_sum, edge_weights, leaf_graph)

    return edge_weights_sum / perimeter
Пример #2
0
 def test_vertex_perimeter2(self):
     g = hg.get_4_adjacency_graph((2, 3))
     hg.set_attribute(g, "no_border_vertex_out_degree", None)
     ref = np.asarray(((2, 3, 2),
                       (2, 3, 2)))
     res = hg.attribute_vertex_perimeter(g)
     self.assertTrue(np.allclose(ref, res))
Пример #3
0
 def test_vertex_perimeter_rag(self):
     g = hg.get_4_adjacency_graph((2, 3))
     vertex_labels = np.asarray(((1, 2, 2), (3, 3, 3)))
     rag = hg.make_region_adjacency_graph_from_labelisation(
         g, vertex_labels)
     ref = np.asarray((2, 3, 3))
     res = hg.attribute_vertex_perimeter(rag)
     self.assertTrue(np.allclose(ref, res))
Пример #4
0
def binary_partition_tree_MumfordShah_energy(graph,
                                             vertex_values,
                                             vertex_area=None,
                                             vertex_perimeter=None,
                                             edge_length=None,
                                             squared_vertex_values=None):
    """
    Binary partition tree according to the Mumford-Shah energy with a constant piecewise model.

    The distance between two regions is equal to the apparition scale of the merged region.

    See:

        Laurent Guigues, Jean Pierre Cocquerez, Hervé Le Men.
        `Scale-sets Image Analysis. International <https://hal.archives-ouvertes.fr/hal-00705364/file/ijcv_scale-setV11.pdf>`_
        Journal of Computer Vision, Springer Verlag, 2006, 68 (3), pp.289-317


    :param graph: input graph
    :param vertex_values: Sum of values inside each vertex of the input graph (1d array for scalar value or 2d array for
        vectorial values, e.g. RGB pixel values)
    :param vertex_area: area of the vertices of the input graph (provided by :func:`~higra.attribute_vertex_area` on `graph`)
    :param vertex_perimeter: perimeter of the vertices of the input graph (provided by :func:`~higra.attribute_vertex_perimeter` on `graph`)
    :param edge_length: length of the frontier represented by the edges of the input graph
        (provided by :func:`~higra.attribute_edge_length` on `graph`)
    :param squared_vertex_values: Sum of squared values inside each vertex of the input graph (1d array for scalar
        value or 2d array for vectorial values, e.g. RGB pixel values).
        If this argument is not provided, it will default to `vertex_values * vertex_values` which is only correct if a
        vertex contains a single value.
    :return: a tree (Concept :class:`~higra.CptHierarchy`) and its node altitudes
    """
    if vertex_area is None:
        vertex_area = hg.attribute_vertex_area(graph)

    if edge_length is None:
        edge_length = hg.attribute_edge_length(graph)

    if vertex_perimeter is None:
        vertex_perimeter = hg.attribute_vertex_perimeter(graph, edge_length)

    vertex_values = hg.linearize_vertex_weights(vertex_values, graph)
    vertex_area = hg.linearize_vertex_weights(vertex_area, graph)
    vertex_perimeter = hg.linearize_vertex_weights(vertex_perimeter, graph)

    if squared_vertex_values is None:
        squared_vertex_values = vertex_values * vertex_values

    tree, altitudes = hg.cpp._binary_partition_tree_MumfordShah_energy(
        graph,
        vertex_perimeter,
        vertex_area,
        vertex_values,
        squared_vertex_values,
        edge_length)

    hg.CptHierarchy.link(tree, graph)

    return tree, altitudes
Пример #5
0
def attribute_contour_length(tree,
                             vertex_perimeter=None,
                             edge_length=None,
                             leaf_graph=None):
    """
    Length of the contour (perimeter) of each node of the given tree.

    :param tree: input tree (Concept :class:`~higra.CptHierarchy`)
    :param vertex_perimeter: perimeter of each vertex of the leaf graph (provided by :func:`~higra.attribute_vertex_perimeter` on `leaf_graph`)
    :param edge_length: length of each edge of the leaf graph (provided by :func:`~higra.attribute_edge_length` on `leaf_graph`)
    :param leaf_graph: (deduced from :class:`~higra.CptHierarchy`)
    :return: a 1d array
    """

    if vertex_perimeter is None:
        vertex_perimeter = hg.attribute_vertex_perimeter(leaf_graph)

    if edge_length is None:
        edge_length = hg.attribute_edge_length(leaf_graph)

    if leaf_graph is not None:
        vertex_perimeter = hg.linearize_vertex_weights(vertex_perimeter,
                                                       leaf_graph)

    frontier_length = hg.attribute_frontier_length(tree, edge_length,
                                                   leaf_graph)
    perimeter = hg.accumulate_and_add_sequential(tree, -2 * frontier_length,
                                                 vertex_perimeter,
                                                 hg.Accumulators.sum)

    # hg.cpp._attribute_contour_length_component_tree is more efficient than the partition tree
    # algorithm but it does not work for tree of shapes left in original space (the problem is that
    # two children of a node may become adjacent when the interpolated pixels are removed).

    # if tree.category() == hg.TreeCategory.PartitionTree:
    #     frontier_length = hg.attribute_frontier_length(tree, edge_length, leaf_graph)
    #     perimeter = hg.accumulate_and_add_sequential(tree, -2 * frontier_length, vertex_perimeter,
    #                                                  hg.Accumulators.sum)
    # elif tree.category() == hg.TreeCategory.ComponentTree:
    #     perimeter = hg.cpp._attribute_contour_length_component_tree(tree, leaf_graph, vertex_perimeter,
    #                                                                 edge_length)

    return perimeter
Пример #6
0
 def test_vertex_perimeter(self):
     g = hg.get_4_adjacency_graph((2, 3))
     ref = np.asarray(((4, 4, 4), (4, 4, 4)))
     res = hg.attribute_vertex_perimeter(g)
     self.assertTrue(np.allclose(ref, res))