Пример #1
0
 def alpha_expansion_step(self):
     """Solve maxflow problem for 2-labeled graph with chosen alpha
     """
     self.calculate_weights_of_two_label_graph()
     self.update_weights_of_two_label_graph()
     # Create the graph
     g = maxflow.Graph[float]()
     # Add the nodes. nodeids has the identifiers of the nodes in the grid
     nodeids = g.add_grid_nodes((self.height, self.width))
     for i in range(self.height):
         for j in range(self.width):
             for n in range(4):
                 if neighbor_exists(i, j, n, self.height, self.width):
                     i_n, j_n = get_neighbor_coordinate(i, j, n)
                     # Add non-terminal edges
                     g.add_edge(nodeids[i, j], nodeids[i_n, j_n],
                                self.edges[i, j, n, 0,
                                           1], self.edges[i, j, n, 1, 0])
             # Add terminal edges
             g.add_tedge(nodeids[i, j], self.nodes[i, j, 0],
                         self.nodes[i, j, 1])
     # Find the maximum flow
     g.maxflow()
     segments = g.get_grid_segments(nodeids)
     self.update_labeling(segments)
def sample_input_image(height, width, beta, iterations):
    """Generation of image using Gibbs sampler

    Parameters
    ----------
    height: unsigned integer
        Image height
    widht: unsigned integer
        Image width
    beta: number
        Weight of edge if its labels differ
    iterations: unsigned integer
        Number of iterations of image generation

    Retunrs
    -------
    matrix of binary values of size (height, width)
        Generated binary image
    """
    print("Generating input image", height, "x", width)
    image = random.randint(2, size=(height, width))  # U{0, 1}
    for iteration in range(iterations):
        for i in range(height):
            for j in range(width):
                zero_weight = 0  # sum of edges weights going from zero label
                unit_weight = 0  # sum of edges weights going from unit label
                for n in range(4):  # for all neighbors
                    if neighbor_exists(height, width, i, j, n):
                        i_n, j_n = get_neighbor_coordinate(i, j, n)
                        zero_weight += edge_weight(0, image[i_n, j_n], beta)
                        unit_weight += edge_weight(1, image[i_n, j_n], beta)
                t = exp(-zero_weight) / (exp(-zero_weight) + exp(-unit_weight))
                image[i, j] = int(random.uniform() >= t)  # U [0, 1]
    return image
Пример #3
0
def calculate_energy(labeling, noised_image, psilon, beta):
    energy = 0
    height, width = labeling.shape
    for i in range(height):
        for j in range(width):
            energy += node_weight(labeling[i, j], noised_image[i, j], epsilon)
            for n in range(4):
                if neighbor_exists(height, width, i, j, n):
                    i_n, j_n = get_neighbor_coordinate(i, j, n)
                    energy += edge_weight(labeling[i, j], labeling[i_n, j_n],
                                          beta)
    return energy
Пример #4
0
 def update_weights_of_two_label_graph(self):
     """Update weights of nodes and edges so that parallel edges have zero costs
     """
     for i in range(self.height):
         for j in range(self.width):
             k = self.labeling[i, j]
             for n in range(4):
                 if neighbor_exists(i, j, n, self.height, self.width):
                     i_n, j_n = get_neighbor_coordinate(i, j, n)
                     k_n = self.labeling[i_n, j_n]
                     a = self.edge_weight(k, k_n)
                     b = self.edge_weight(self.alpha, k_n)
                     c = self.edge_weight(k, self.alpha)
                     d = self.edge_weight(self.alpha, self.alpha)
                     self.nodes[i, j, 1] = d - c
                     self.nodes[i_n, j_n, 0] = a
                     self.nodes[i_n, j_n, 1] = c
                     self.edges[i, j, n, 0, 0] = 0
                     self.edges[i, j, n, 0, 1] = 0
                     self.edges[i, j, n, 1, 1] = 0
                     self.edges[i, j, n, 1, 0] = b + c - a - d
Пример #5
0
def gibbs_iteration(labeling, height, width, epsilon, beta):
    """One iteration of Gibbs sampler

    Parameters
    ----------
    labeling: matrix of image size with binary values
        Current labeling
    height: unsigned int
        Image height
    widht: unsigned int
        Image width
    epsilon: number
        Noise level
    beta: number
        Weight of edge if its labels differ

    Returns
    -------
    matrix of image size with binary values
        Updated labeling
    """
    for i in range(height):
        for j in range(width):
            sum_zero_edges = 0
            sum_unit_edges = 0
            for n in range(4):
                if neighbor_exists(height, width, i, j, n):
                    i_n, j_n = get_neighbor_coordinate(i, j, n)
                    sum_zero_edges += edge_weight(0, noised_image[i_n, j_n],
                                                  beta)
                    sum_unit_edges += edge_weight(1, noised_image[i_n, j_n],
                                                  beta)
            zero = exp(-node_weight(0, noised_image[i, j], epsilon) -
                       sum_zero_edges)
            unit = exp(-node_weight(1, noised_image[i, j], epsilon) -
                       sum_unit_edges)
            t = zero / (zero + unit)
            labeling[i, j] = int(random.uniform() >= t)  # U[0, 1]
    return labeling
Пример #6
0
def maxflow_image_restoration(noised_image, beta, epsilon):
    """Simple maxflow binary image restoration

    Parameters
    ----------
    noised_image: matrix of binary values
        Generated image after noising

    Returns
    -------
    matrix of binary values
        Restored image
    """
    # Create the graph
    g = maxflow.Graph[float]()
    # Add the nodes. nodeids has the identifiers of the nodes in the grid
    height, width = noised_image.shape
    nodeids = g.add_grid_nodes((height, width))
    for i in range(height):
        for j in range(width):
            for n in range(4):
                if neighbor_exists(height, width, i, j, n):
                    i_n, j_n = get_neighbor_coordinate(i, j, n)
                    weight = edge_weight(noised_image[i, j],
                                         noised_image[i_n, j_n], beta)
                    # Add non-terminal edges
                    g.add_edge(nodeids[i, j], nodeids[i_n, j_n], weight,
                               weight)
            # Add terminal edges
            g.add_tedge(nodeids[i, j],
                        node_weight(0, noised_image[i, j], epsilon),
                        node_weight(1, noised_image[i, j], epsilon))
    # Find the maximum flow
    g.maxflow()
    sgm = g.get_grid_segments(nodeids)
    # Get the segments of the nodes in the grid
    # The labels should be 1 where sgm is False and 0 otherwise
    resulting_image = int_(logical_not(sgm))
    return resulting_image
Пример #7
0
 def calculate_weights_of_two_label_graph(self):
     """Calculate weights of nodes and edges for two-label graph
     """
     self.nodes = zeros((self.height, self.width, 2))
     self.edges = zeros((self.height, self.width, 4, 2, 2))
     for i in range(self.height):
         for j in range(self.width):
             k = self.labeling[i, j]
             self.nodes[i, j, 0] = self.node_weight(self.image[i, j], k)
             self.nodes[i, j, 1] = self.node_weight(self.image[i, j],
                                                    self.alpha)
             for n in range(4):
                 if neighbor_exists(i, j, n, self.height, self.width):
                     i_n, j_n = get_neighbor_coordinate(i, j, n)
                     k_n = self.labeling[i_n, j_n]
                     self.edges[i_n, j_n, n, 0,
                                1] = self.edge_weight(k, self.alpha)
                     self.edges[i_n, j_n, n, 1,
                                0] = self.edge_weight(self.alpha, k_n)
                     self.edges[i_n, j_n, n, 0,
                                0] = self.edge_weight(k, k_n)
                     self.edges[i_n, j_n, n, 1, 1] = self.edge_weight(
                         self.alpha, self.alpha)