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
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
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
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
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
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)