Пример #1
0
def solve_iterative(W, iterations=10):

    """Find an approximate minimizer of (x.T * W * x) for x_i in {-1, 1}.

    Args:
        W: matrix of weights.
        iterations: number of iterations of finding submodular sub-matrices and
           solving them in random order.

    Returns:
        vector x of {-1, 1}.

    See Algorithm 1 from Zhuang et al. http://arxiv.org/abs/1603.02844

    """

    # ignore the diagonal, and symmetrize
    W = W.copy()
    W.setdiag(0)
    W = (W + W.T) / 2

    num_elements = W.shape[0]

    # initial guess of all 1s
    current_labels = 0 * (np.random.randint(2, size=num_elements) * 2 - 1)

    for _ in range(iterations):
        for sub_W, active_indices in generate_submodular(W):
            sub_W = sub_W.astype(np.float32)  # pymaxflow compatibility
            num_active = len(active_indices)

            print("solve", active_indices, "\n", sub_W)

            # We are solving for active_indices.
            # All others are held fixed.
            # These are the costs relative to the labels we are holding fixed.
            costs_wrt_fixed = W.dot(current_labels)[active_indices]
            print("costs", costs_wrt_fixed)
            costs_wrt_fixed = costs_wrt_fixed.astype(np.float32)  # pymaxflow compatibility

            # split into positive and negative pieces
            pos_costs_wrt_fixed = costs_wrt_fixed.copy()
            neg_costs_wrt_fixed = - costs_wrt_fixed
            pos_costs_wrt_fixed[pos_costs_wrt_fixed < 0] = 0
            neg_costs_wrt_fixed[neg_costs_wrt_fixed < 0] = 0

            # set up a graphcut problem for this sub_W.
            # source = 1, sink = -1 (later mapped to 0).
            # Costs should be mapped to cuts.
            #
            #     source == 1
            #        |
            #        |  cost of A == -1  (neg_costs_wrt_fixed)
            #        |
            #        A
            #        |
            #        | cost of A == 1    (pos_costs_wrt_fixed)
            #        |
            #      sink == -1

            g = pymaxflow.PyGraph(num_active, num_active ** 2)
            g.add_node(num_active)
            # add max capacity to ensure flow is possible.  (I'm not sure this is necessary.)
            g.add_tweights_vectorized(np.arange(num_active, dtype=np.int32),
                                      2 * neg_costs_wrt_fixed,  # source capacity
                                      2 * pos_costs_wrt_fixed)  # sink capacity

            # add edges between labels
            row, col = np.nonzero(sub_W)
            # multiply by -2 because:
            #   if labels i,j are the same, score += W[i, j]
            #   if labels i,j are different (i.e., 1 & -1), score -= W[i, j]
            #   relative cost of separating vs. not = -2 * W[i, j]
            vals = -2 * sub_W[row, col]
            assert np.all(vals >= 0)
            g.add_edge_vectorized(row.astype(np.int32), col.astype(np.int32), vals, vals)

            g.maxflow()
            out = (g.what_segment_vectorized() == pymaxflow.SOURCE) * 2 - 1
            print("res", out)

            # validate solution
            best = np.inf
            for possible in itertools.product([-1, 1], repeat=num_active):
                v = np.array(possible)
                e = sub_W.dot(v).dot(v) + costs_wrt_fixed.dot(v)
                if e < best:
                    best_v = v
                    best = e
            print("best", best_v, best)

            # set active labels to new configuration
            current_labels[active_indices] = out
            print ("NEW", best_v, active_indices, current_labels)
            print("")

    print ("C", current_labels, W.dot(current_labels).dot(current_labels))
    return (current_labels + 1) / 2
Пример #2
0
 def create_graph(vertices_count, edges_count):
     return pymaxflow.PyGraph(vertices_count, edges_count)
Пример #3
0
def graphCutSegment(costs_class0,costs_class1,imlabelsBinary):

	H=costs_class0.shape[0]
	W=costs_class0.shape[1]
	nbpixels=H*W 

	# -----------------------Segmentation method using regional data term and constant edge cost-------------------------------
	
	g = pymaxflow.PyGraph(nbpixels,nbpixels * 2)
	g.add_node(nbpixels)


	# TODO 
	# encode unary term of the energy in slide 25 (sum_p Dp(fp) +sum_pq Vqp(fq,fp))
	# by adding arcs in the graph by calling the function g.add_tweights_vectorized 
	# this function allows to add arcs between nodes and the source node s and a the sink node t (oriented as source->node and node->target)
	# g.add_tweights_vectorized(indices_nodes,costs_arcs_from_s_to_nodes,costs_arcs_from_nodes_to_t) 
	# with indices_nodes,costs_arcs_from_s_to_nodes,costs_arcs_from_nodes_to_t vector whose lenght is the number of pixels
	# WARNING, in the contrary to the slide  24 , the pymaxflow code seems to use the convention 
	# that s is in the set of node with labels 0 and t is in the set of node with labels 1
	# look at the graph slide 24 to see how to go from Dp(0) and Dp(1) to the arc weights keeping 
	# in mind that pymaxflow use a opposite convention
	# make sure that indices_nodes,costs_arcs_to_s and costs_arcs_to_t are vectors of the same size
	# otherwise will get an assertion error 
	# Note :the unvectorized version is documented in the graph.h file un pymaxflow


	#indices =?
	#costs_arcs_from_s_to_nodes= ?
	#costs_arcs_from_nodes_to_t= ? 
	g.add_tweights_vectorized(indices.astype(np.int32),costs_arcs_from_s_to_nodes.astype(np.float32),costs_arcs_from_nodes_to_t.astype(np.float32))


	#We check that the minimization of this energy without extra node gives back the same labels as imlabelsBinary
	print("calling maxflow")
	g.maxflow()
	out = g.what_segment_vectorized()    
	imlabels2=out.reshape((H,W))
	assert(np.all(imlabelsBinary==imlabels2))

	# TODO
	# encode binary terms of the energy in slide 25 (sum_p Dp(fp) +sum_pq Vqp(fq,fp))
	# by considering first horizontal edges between neighboring pixels then vertical edges
	# you  add oriented arcs in the graph between nodes by calling the function g.add_edge_vectorized
	# g.add_edge_vectorized(indices_node_i,indices_node_j,weight_arc_i_to_j,weight_arc_j_to_i)
	# in our case we use weight_arc_i_to_j=weight_arc_i_to_j=alpha
	# first create a matrix indices = np.arange(nbpixels) .reshape(H,W) an use 
	# then use submaxtrices extracted from  indices then flattened to create indices_node_i and indices_node_j
	# Note : you can have a look on the example in test.py in the pymaxflow directory

	alpha=0.1


	#------ adding horizontal edges------
	indices = np.arange(nbpixels) .reshape(H,W).astype(np.int32)
	#indices_node_i = ?
	#indices_node_j = ?
	#cost_diff= ?
	g.add_edge_vectorized(indices_node_i, indices_node_j, cost_diff ,cost_diff)  


	#------ adding vertical edges------
	#indices_node_i = ?
	#indices_node_j = ?
	#cost_diff=n ?  
	g.add_edge_vectorized(indices_node_i, indices_node_j, cost_diff, cost_diff)  

	# Getting the result image
	print("calling maxflow")
	g.maxflow()
	out = g.what_segment_vectorized()
	

	imlabelsGC=out.reshape((H,W)) 
	return imlabelsGC
Пример #4
0
                        center_coords] += gap_completion_distances[:, :, di2][
                            intermediate_coords]
                    di2reverse = (di2 + 4) % 8
                    inflow_smooth[
                        center_coords] += smooth_distances[:, :, di2reverse][
                            exterior_coords]
                    inflow_gap[
                        center_coords] += gap_completion_distances[:, :, di2reverse][
                            exterior_coords]

        for smoothing_factor in smoothing_factors:
            for gap_completion_factor in gap_completion_factors:
                with timer.Timer("setup"):

                    flow_graph = pymaxflow.PyGraph(
                        terminal_matrix_prob.shape[0],
                        8 * terminal_matrix_prob.shape[0])

                    flow_graph.add_node(terminal_matrix_prob.shape[0])

                    ## Load the terminal matrix
                    terminal_matrix = terminal_matrix_prob + \
                        terminal_matrix_smooth * smoothing_factor + \
                        terminal_matrix_gap_completion * gap_completion_factor

                    flow_graph.add_tweights_vectorized(
                        node_indices.ravel(), terminal_matrix[:, 0].ravel(),
                        terminal_matrix[:, 1].ravel())

                    # compute the source/sink difference for the nodes
                    source_sink_cap = terminal_matrix[:,0].flatten() - \
Пример #5
0
import sys
import pymaxflow
import pylab
import numpy as np

eps = 0.01

im = pylab.imread(sys.argv[1]).astype(np.float32)

indices = np.arange(im.size).reshape(im.shape).astype(np.int32)
g = pymaxflow.PyGraph(im.size, im.size * 3)

g.add_node(im.size)

# adjacent
diffs = np.abs(im[:, 1:] - im[:, :-1]).ravel() + eps
e1 = indices[:, :-1].ravel()
e2 = indices[:, 1:].ravel()
g.add_edge_vectorized(e1, e2, diffs, 0 * diffs)

# adjacent up
diffs = np.abs(im[1:, 1:] - im[:-1, :-1]).ravel() + eps
e1 = indices[1:, :-1].ravel()
e2 = indices[:-1, 1:].ravel()
g.add_edge_vectorized(e1, e2, diffs, 0 * diffs)

# adjacent down
diffs = np.abs(im[:-1, 1:] - im[1:, :-1]).ravel() + eps
e1 = indices[:-1, :-1].flatten()
e2 = indices[1:, 1:].ravel()
g.add_edge_vectorized(e1, e2, diffs, 0 * diffs)