Example #1
0
    def test_label_costs_graph(self):
        """Test the label_costs argument with cut_from_graph."""
        unaries, pairwise, edges, expected = self.binary_data()
        # Give a slight preference to class 0
        unaries[:, :, 1] += 1

        result = cut_from_graph(edges, unaries.reshape(-1, 2), pairwise, label_cost=1)
        result = result.reshape(unaries.shape[:2])
        self.assertTrue(np.array_equal(result, expected))

        # Try again with a very high label cost to collapse to a single label
        result = cut_from_graph(edges, unaries.reshape(-1, 2), pairwise, label_cost=1000)
        result = result.reshape(unaries.shape[:2])
        self.assertTrue(np.array_equal(result, np.zeros_like(result)))
Example #2
0
    def test_label_costs_graph(self):
        """Test the label_costs argument with cut_from_graph."""
        unaries, pairwise, edges, expected = self.binary_data()
        # unaries, pairwise, edges, expected = self.binary_data_float()
        # Give a slight preference to class 0
        unaries[:, :, 1] += 1

        label_cost = np.array([1, 1])
        # label_cost = np.random.rand(2)

        weight = np.random.rand(edges.shape[0]).astype(np.float32)

        unaries = unaries.astype(np.float32)
        pairwise = pairwise.astype(np.float32)
        label_cost = label_cost.astype(np.float32)
        print(unaries, unaries.dtype)
        print(pairwise, pairwise.dtype)
        print(edges.shape)
        print(expected, expected.dtype)
        print(label_cost, label_cost.dtype)

        result = cut_from_graph(edges, weight, unaries.reshape(-1, 2),
                                pairwise, label_cost)
        result = result.reshape(unaries.shape[:2])
        print(result)
        self.assertTrue(np.array_equal(result, expected))
Example #3
0
def cut_graph_profile(cellGraph,
                      Kmean_labels,
                      unary_scale_factor=100,
                      smooth_factor=50,
                      label_cost=10,
                      algorithm='expansion'):
    '''
    Returns new labels and gmm for the cut.
    
    :param points: cellGraph (n,3); count: shape (n,); 
    :unary_scale_factor, scalar; smooth_factor, scalar; 
    :label_cost: scalar; algorithm='expansion'
    :rtype: label shape (n,); gmm object.
    '''

    smooth_factor = smooth_factor
    unary_scale_factor = unary_scale_factor
    label_cost = label_cost
    algorithm = algorithm
    uniq, count = np.unique(Kmean_labels, return_counts=True)
    unary_cost = compute_unary_cost_profile(Kmean_labels, unary_scale_factor)
    pairwise_cost = compute_pairwise_cost(len(uniq), smooth_factor)
    edges = cellGraph[:, 0:2].astype(np.int32)
    labels = pygco.cut_from_graph(edges, unary_cost, pairwise_cost, label_cost)
    #    energy = compute_energy(unary_cost, pairwise_cost, edges, labels)

    return labels
Example #4
0
 def run_inference(model,
                   thresh=None,
                   n_labels=None,
                   n_iter=5,
                   algorithm='expansion'):
     import pygco
     if n_labels is not None:
         model._update_labels(n_labels)
     if thresh is not None:
         model._update_weights(thresh=thresh)
     if model.n_labels <= 0:
         raise ValueError('cannot run inference with zero labels')
     if model.n_labels == 1:
         labeling = np.zeros(model.n_nodes, dtype=np.int32)
     else:
         cutkw = dict(n_iter=n_iter, algorithm=algorithm)
         if 0:
             print(ut.code_repr(model.unaries, 'unaries'))
             print(ut.code_repr(model.weighted_edges, 'weighted_edges'))
             print(ut.code_repr(model.pairwise_potts, 'pairwise_potts'))
             print(ut.code_repr(cutkw, 'cutkw'))
         labeling = pygco.cut_from_graph(model.weighted_edges,
                                         model.unaries,
                                         model.pairwise_potts, **cutkw)
         model.labeling = labeling
     #print('model.total_energy = %r' % (model.total_energy,))
     return labeling
Example #5
0
    def test_cut_from_grpah(self):
        """Test the cut_from_graph method."""
        unaries, pairwise, edges, expected = self.binary_data()

        result = cut_from_graph(edges, unaries.reshape(-1, 2), pairwise)
        result = result.reshape(unaries.shape[:2])

        self.assertTrue(np.array_equal(result, expected))
Example #6
0
def constantEdges() :
    edges = []
    with open(PATH + 'edges.csv', 'rb') as f :
        reader = csv.reader(f)
        reader.next()
        for row in reader :
            edges.append(row)
    edges = np.array(edges, dtype='int32', ndmin=2)
    edges = edges - 1

    unary = []
    with open(PATH + 'unary.csv', 'rb') as f :
        reader = csv.reader(f)
        reader.next()
        for row in reader :
            unary.append(row)

    unary = np.array(unary, dtype = "float32")
    unary = (-100 * unary).copy("C").astype(np.int32)

    edge_weights = []
    with open(PATH + 'edge_weights.csv', 'rb') as f :
        reader = csv.reader(f)
        reader.next()
        for row in reader :
            edge_weights.append(row)
            
    edge_weights = np.array(edge_weights, dtype = "int32")
    edge_weights.shape = (len(edges),)

    
    num_blocks, num_labels = unary.shape


    pairwise = -50 * np.eye(num_labels, dtype=np.int32)
#    pairwise[:, num_labels-1] = -40
#    pairwise[num_labels-1, :] = -40
#    pairwise[num_labels-1, num_labels-1] = -50

    print pairwise


    edge_weights.shape = (len(edge_weights), 1)
    
    edges = np.concatenate((edges, edge_weights), axis=1)


    (result_graph, energy) = cut_from_graph(edges, unary, pairwise, algorithm="swap", n_iter = -1)

    print energy

    print energy_of_graph_assignment(edges, unary, pairwise, result_graph)

    with open(PATH + 'potts_labels.csv', 'wb') as f:
        writer = csv.writer(f)
        writer.writerow(['label'])
        for label in result_graph :
            writer.writerow([label + 1])
    def segment_edge_cut(self):
        # noinspection PyUnresolvedReferences
        from pygco import cut_from_graph

        height = self.image.shape[0]
        width = self.image.shape[1]

        # first, we construct the grid graph
        # inds is a matrix of cell indices
        inds = np.arange(height * width).reshape(height, width)
        # list of all horizontal and vertical edges
        horizontal_edges = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
        vertical_edges = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
        # concatenate both lists
        edges = np.vstack([horizontal_edges, vertical_edges]).astype(np.int32)

        # the edge weight multiplies the logarithm of the probability, this is the same as potentiating the probability
        # and renormalizing
        def effective_probability(probability, weight):
            return probability ** weight / (probability ** weight + (1 - probability) ** weight)

        depth = self.feature_images['depth'].reshape(-1)
        depth[depth == -1] = np.nan

        self.edge_depth_diff = np.abs(depth[edges[:, 0]] - depth[edges[:, 1]])

        weights = np.ones([edges.shape[0], 1])  # weight is 1 for nan
        depth_diff_thres = 0.02  # in m

        # replace nans with threshold to prevent comparing to nan warnings
        self.edge_depth_diff[np.isnan(self.edge_depth_diff)] = depth_diff_thres
        smooth_depth_edges = self.edge_depth_diff < depth_diff_thres
        sharp_depth_edges = self.edge_depth_diff > depth_diff_thres

        weights[smooth_depth_edges] = 2  # effective for 0.95 + weight 2 -> 0.9972375
        weights[sharp_depth_edges] = 0

        # add this for displaying the depth edges
        self.depth_edge_image = np.zeros(height * width)
        self.depth_edge_image[edges[smooth_depth_edges].reshape(-1)] = -1
        self.depth_edge_image[edges[sharp_depth_edges].reshape(-1)] = 1
        self.depth_edge_image = self.depth_edge_image.reshape(height, width)

        edges = np.hstack([edges, weights])

        # compute potentials (log of probabilities)
        unaries = -np.log(np.array([np.clip(self.posterior_images[o],a_min=0.01, a_max=1.0) for o in self.candidate_objects])).transpose((1, 2, 0))
        num_labels = unaries.shape[2]
        p_same_label = 0.95
        pairwise = -np.log(1 - p_same_label) * (1 - np.eye(num_labels)) - np.log(p_same_label) * np.eye(num_labels)

        k = 10  # scaling factor for potentials to reduce aliasing because the potentials need to be converted to integers

        unaries_c = np.copy((k * unaries).astype('int32'), order='C').reshape(-1, num_labels)
        pairwise_c = np.copy((k * pairwise).astype('int32'), order='C')
        edges_c = edges.astype('int32')
        self.segmentation = cut_from_graph(edges_c, unaries_c, pairwise_c).reshape(height, width)
Example #8
0
def graphcut_edge_weight(unary_costs, color_vars, centroids, alpha_val=alpha):
    #unary_costs_int32 = (alpha*unary_costs).astype('int32')
    unary_cost_list = np.zeros(
        (np.shape(unary_costs)[0] * np.shape(unary_costs)[1],
         np.shape(unary_costs)[2]))
    rows = np.shape(unary_costs)[0]
    cols = np.shape(unary_costs)[1]

    edges_weights = []

    for r in range(rows):
        for c in range(cols):
            unary_cost_list[get_list_index(r, c, cols), :] = unary_costs[r,
                                                                         c, :]

            row_safe = r != rows - 1
            col_safe = c != cols - 1
            if (row_safe):
                edges_weights.append([
                    get_list_index(r, c, cols),
                    get_list_index(r + 1, c, cols),
                    get_weight(r, c, r + 1, c, color_vars)
                ])
            if (col_safe):
                edges_weights.append([
                    get_list_index(r, c, cols),
                    get_list_index(r, c + 1, cols),
                    get_weight(r, c, r, c + 1, color_vars)
                ])
            if (row_safe and col_safe):
                edges_weights.append([
                    get_list_index(r, c + 1, cols),
                    get_list_index(r + 1, c, cols),
                    get_weight(r, c + 1, r + 1, c, color_vars)
                ])
                edges_weights.append([
                    get_list_index(r + 1, c, cols),
                    get_list_index(r, c + 1, cols),
                    get_weight(r + 1, c, r, c + 1, color_vars)
                ])

    edges_weights_int32 = np.array(edges_weights).astype('int32')
    binary_costs_int32 = get_binary_costs(centroids)
    unary_cost_list_int32 = (alpha_val * unary_cost_list).astype('int32')

    test_labels_list = pygco.cut_from_graph(edges_weights_int32,
                                            unary_cost_list_int32,
                                            binary_costs_int32,
                                            n_iter=-1,
                                            algorithm='swap')

    test_labels = np.zeros(
        (np.shape(unary_costs)[0], np.shape(unary_costs)[1]))
    for r in range(rows):
        for c in range(cols):
            test_labels[r, c] = test_labels_list[get_list_index(r, c, cols)]
    return test_labels.astype('int')
Example #9
0
    def set_data(self, data, voxels1, voxels2, seeds = False, hard_constraints = True):
        """
        Setting of data.
        You need set seeds if you want use hard_constraints.
        
        """
        mdl = Model ( modelparams = self.modelparams )
        mdl.train(voxels1, 1)
        mdl.train(voxels2, 2)
        #pdb.set_trace();
        #tdata = {}
# as we convert to int, we need to multipy to get sensible values

# There is a need to have small vaues for good fit
# R(obj) = -ln( Pr (Ip | O) )
# R(bck) = -ln( Pr (Ip | B) )
# Boykov2001a 
# ln is computed in likelihood 
        tdata1 = (-(mdl.likelihood(data, 1))) * 10
        tdata2 = (-(mdl.likelihood(data, 2))) * 10

        #pyed = py3DSeedEditor.py3DSeedEditor(tdata1)
        #pyed = py3DSeedEditor.py3DSeedEditor(seeds)
        #pyed.show()
        #pdb.set_trace();

        if hard_constraints: 
            #pdb.set_trace();
            if (type(seeds)=='bool'):
                raise Exception ('Seeds variable  not set','There is need set seed if you want use hard constraints')
            tdata1, tdata2 = self.set_hard_hard_constraints(tdata1, tdata2, seeds)
            


        unariesalt = (1 * np.dstack([tdata1.reshape(-1,1), tdata2.reshape(-1,1)]).copy("C")).astype(np.int32)

# create potts pairwise
        #pairwiseAlpha = -10
        pairwise = -self.gcparams['pairwiseAlpha'] * np.eye(2, dtype=np.int32)
# use the gerneral graph algorithm
# first, we construct the grid graph
        inds = np.arange(data.size).reshape(data.shape)
        edgx = np.c_[inds[:, :, :-1].ravel(), inds[:, :, 1:].ravel()]
        edgy = np.c_[inds[:, :-1, :].ravel(), inds[:, 1:, :].ravel()]
        edgz = np.c_[inds[:-1, :, :].ravel(), inds[1:, :, :].ravel()]
        edges = np.vstack([edgx, edgy, edgz]).astype(np.int32)

# edges - seznam indexu hran, kteres spolu sousedi

# we flatten the unaries
        #result_graph = cut_from_graph(edges, unaries.reshape(-1, 2), pairwise)
        result_graph = cut_from_graph(edges, unariesalt.reshape(-1,2), pairwise)

        
        result_labeling = result_graph.reshape(data.shape)

        return result_labeling
Example #10
0
def example_binary():
    # generate trivial data
    x = np.ones((10, 10))
    x[:, 5:] = -1
    x_noisy = x + np.random.normal(0, 0.8, size=x.shape)
    x_thresh = x_noisy > 0.0

    # create unaries
    unaries = x_noisy
    # as we convert to int, we need to multipy to get sensible values
    unaries = (10 * np.dstack([unaries, -unaries]).copy("C")).astype(np.int32)
    # create potts pairwise
    pairwise = -10 * np.eye(2, dtype=np.int32)

    # do simple cut
    result = cut_simple(unaries, pairwise)

    # generalized Potts potentials
    pix_nums = np.r_[: 10 * 10].reshape(10, 10)
    pairwise_cost = dict(
        [(tuple(sorted(pair)), 30) for pair in zip(pix_nums[:, :-1].flatten(), pix_nums[:, 1:].flatten())]
        + [(tuple(sorted(pair)), 0) for pair in zip(pix_nums[:-1, :].flatten(), pix_nums[1:, :].flatten())]
    )
    result_gp = cut_simple_gen_potts(unaries, pairwise_cost)

    # use the gerneral graph algorithm
    # first, we construct the grid graph
    inds = np.arange(x.size).reshape(x.shape)
    horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
    vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
    edges = np.vstack([horz, vert]).astype(np.int32)

    # we flatten the unaries
    result_graph = cut_from_graph(edges, unaries.reshape(-1, 2), pairwise)

    # generalized Potts potentials
    result_graph_gp = cut_from_graph_gen_potts(unaries.reshape(-1, 2), pairwise_cost)

    # plot results
    plt.subplot(231, title="original")
    plt.imshow(x, interpolation="nearest")
    plt.subplot(232, title="noisy version")
    plt.imshow(x_noisy, interpolation="nearest")
    plt.subplot(233, title="rounded to integers")
    plt.imshow(unaries[:, :, 0], interpolation="nearest")
    plt.subplot(234, title="thresholding result")
    plt.imshow(x_thresh, interpolation="nearest")
    plt.subplot(235, title="cut_simple")
    plt.imshow(result, interpolation="nearest")
    plt.subplot(236, title="cut_from_graph")
    plt.imshow(result_graph.reshape(x.shape), interpolation="nearest")

    plt.show()
def apply_pygco(transforms, pts):
    edges = triangulate_query(pts)
    unaries = compile_transfer_errors(transforms, pts)
    # Outlier label
    unaries = np.insert(unaries, 0, OUTLIER_DISTANCE, axis=1)
    pairwise = PAIRWISE_WEIGHTING * np.eye(len(transforms) + 1).astype(np.int32)

    '''
    print 'edges', edges.shape
    print 'unaries', unaries.shape
    print 'transforms', pairwise.shape

    print 'edges', edges
    print 'unaries', unaries
    print 'transforms', pairwise
    '''

    result = cut_from_graph(edges, unaries, pairwise)

    print 'result', result

    cnt = collections.Counter()
    for label in result:
        cnt[label] += 1

    # While the best label is an outlier label (not a good sign to start)
    counted_items = cnt.items()
    not_outlier = list(sorted(filter(lambda x: x[0] != 0, cnt.items()), key=itemgetter(1), reverse=True))

    print 'not outlier:', not_outlier

    best_label = not_outlier[0][0]
    second_best_label = not_outlier[1][0]

    best_points = []
    second_best_points = []
    for index, label in enumerate(result):
        if label == best_label:
            best_points.append(pts[index])

        elif label == second_best_label:
            second_best_points.append(pts[index])

    best_points_scores = []
    second_best_points_scores = []

    best_points_scores = unaries[:, best_label].tolist()
    second_best_points_scores = unaries[:, second_best_label].tolist()

    return (transforms[best_label - 1], transforms[second_best_label - 1], best_points, second_best_points, best_points_scores, second_best_points_scores)
Example #12
0
 def run_inference(model, thresh=None, n_labels=None, n_iter=5, algorithm='expansion'):
     import pygco
     if n_labels is not None:
         model._update_labels(n_labels)
     if thresh is not None:
         model._update_weights(thresh=thresh)
     if model.n_labels <= 0:
         raise ValueError('cannot run inference with zero labels')
     if model.n_labels == 1:
         labeling = np.zeros(model.n_nodes, dtype=np.int32)
     else:
         cutkw = dict(n_iter=n_iter, algorithm=algorithm)
         labeling = pygco.cut_from_graph(model.weighted_edges, model.unaries,
                                         model.pairwise_potts, **cutkw)
         model.labeling = labeling
     #print('model.total_energy = %r' % (model.total_energy,))
     return labeling
Example #13
0
def example_binary():
    # generate trivial data
    x = np.ones((10, 10))
    x[:, 5:] = -1
    x_noisy = x + np.random.normal(0, 0.8, size=x.shape)
    x_thresh = x_noisy > .0

    # create unaries
    unaries = x_noisy
    # as we convert to int, we need to multipy to get sensible values
    unaries = (10 * np.dstack([unaries, -unaries]).copy("C")).astype(np.int32)
    # create potts pairwise
    pairwise = -10 * np.eye(2, dtype=np.int32)

    # do simple cut
    result = cut_simple(unaries, pairwise)

    # use the gerneral graph algorithm
    # first, we construct the grid graph
    inds = np.arange(x.size).reshape(x.shape)
    horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
    vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
    edges = np.vstack([horz, vert]).astype(np.int32)

    # we flatten the unaries
    result_graph = cut_from_graph(edges, unaries.reshape(-1, 2), pairwise)

    # plot results
    plt.subplot(231, title="original")
    plt.imshow(x, interpolation='nearest')
    plt.subplot(232, title="noisy version")
    plt.imshow(x_noisy, interpolation='nearest')
    plt.subplot(233, title="rounded to integers")
    plt.imshow(unaries[:, :, 0], interpolation='nearest')
    plt.subplot(234, title="thresholding result")
    plt.imshow(x_thresh, interpolation='nearest')
    plt.subplot(235, title="cut_simple")
    plt.imshow(result, interpolation='nearest')
    plt.subplot(236, title="cut_from_graph")
    plt.imshow(result_graph.reshape(x.shape), interpolation='nearest')

    plt.show()
Example #14
0
def example_3d():

    x = np.ones((10, 10, 10))
    x[:, 5:, :] = -1
    x_noisy = x + np.random.normal(0, 0.8, size=x.shape)
    x_thresh = x_noisy > .0

# create unaries
    unaries = x_noisy
# as we convert to int, we need to multipy to get sensible values
    unariesalt = (10 * np.dstack([unaries.reshape(-1,1), -unaries.reshape(-1,1)]).copy("C")).astype(np.int32)
    # unariesa = (10 * unaries).astype(np.int32)
    # unariesb = (-10* unaries).astype(np.int32)
    # unariescol = np.concatenate([unariesa.reshape(-1,1), unariesb.reshape(-1,1)], axis=1).astype(np.int32)
# create potts pairwise
    pairwise = -10 * np.eye(2, dtype=np.int32)
# use the gerneral graph algorithm
# first, we construct the grid graph
    inds = np.arange(x.size).reshape(x.shape)
    edgx = np.c_[inds[:, :, :-1].ravel(), inds[:, :, 1:].ravel()]
    edgy = np.c_[inds[:, :-1, :].ravel(), inds[:, 1:, :].ravel()]
    edgz = np.c_[inds[:-1, :, :].ravel(), inds[1:, :, :].ravel()]
    edges = np.vstack([edgx, edgy, edgz]).astype(np.int32)

    pdb.set_trace()
# we flatten the unaries
    #result_graph = cut_from_graph(edges, unaries.reshape(-1, 2), pairwise)
    result_graph = cut_from_graph(edges, unariesalt.reshape(-1,2), pairwise)

    
    result_labeling = result_graph.reshape(x.shape)

#show results for 3th slice
    plt.subplot(311, title="original")
    plt.imshow(x[:,:,3], interpolation='nearest')
    plt.subplot(312, title="noisy version")
    plt.imshow(x_noisy[:,:,3], interpolation='nearest')
    plt.subplot(313, title="cut_from_graph")

    plt.imshow(result_labeling[:,:,3], interpolation='nearest')
    plt.show()
Example #15
0
    def solve(self, unary_term, pairwise_term, k):
        '''
        Args :
            unary_term - Numpy 2d array [nvertex, nlabel]
                unary_term term to be minimized
            pairwise_term - Numpy 2d array [nvertex, nvertex]
                pairwise_term term to be minimized
            k - int
        '''
        assert unary_term.shape[1]==self.nlabel, "Unary term have wrong labels"
        nvertex = unary_term.shape[0]
        assert pairwise_term.shape==(nvertex, nvertex), "Pairwise term  haver wrong shape"
        
        unary_term = unary_term*self.value1*self.value2
        unary_term = unary_term.astype(np.int32)
        
        nedges = nvertex*(nvertex-1)/2
        nedges = int(nedges)
        self.edges = np.zeros([nedges, 3], dtype=np.float32)
        
        idx = 0
        for i in range(nvertex):
            for j in range(i+1, nvertex):
                self.edges[idx] = [i, j, -self.value2*pairwise_term[i][j]]
                idx+=1
 
        self.edges = self.edges.astype(np.int32)

        binary_vector = np.zeros([nvertex, self.nlabel], dtype=np.float32) 
        energy = 0
        keep = unary_term
        for _ in range(k):
            results = cut_from_graph(edges=self.edges, unary_cost=unary_term, pairwise_cost=self.pairwise_cost, n_iter=self.niter, algorithm='swap') 
            for i, j in enumerate(results): 
                binary_vector[i][j] = 1
                unary_term[i][j] = np.iinfo(np.int32).max//2

        return binary_vector
Example #16
0
def cut_graph_general_profile(cellGraph, count,gmm, unary_scale_factor=100, 
                      smooth_factor=50, label_cost=10, algorithm='expansion'):
    '''
    Returns new labels and gmm for the cut with gmm profile.
    
    :param points: cellGraph (n,3); count: shape (n,); 
    :unary_scale_factor, scalar; smooth_factor, scalar; 
    :label_cost: scalar; algorithm='expansion'
    :rtype: label shape (n,); gmm object.
    '''
    unary_scale_factor = unary_scale_factor
    label_cost = label_cost
    algorithm = algorithm
    smooth_factor = smooth_factor
    gmm=gmm      
    unary_cost = compute_unary_cost_simple_profile(count, gmm, unary_scale_factor)
    
    pairwise_cost = compute_pairwise_cost(gmm.means_.shape[0], smooth_factor)
    edges = cellGraph[:,0:2].astype(np.int32)
    labels = pygco.cut_from_graph(edges, unary_cost, pairwise_cost, label_cost)
#    energy = compute_energy(unary_cost, pairwise_cost, edges, labels)

    return labels
Example #17
0
def cut_graph_general(cellGraph, count,gmm, unary_scale_factor=100, 
                      smooth_factor=30, label_cost=10, algorithm='expansion',
                      profile=False):
    '''
    Returns new labels and gmm for the cut.
    
    :param points: cellGraph (n,3); count: shape (n,); 
    :unary_scale_factor, scalar; smooth_factor, scalar; 
    :label_cost: scalar; algorithm='expansion'
    :rtype: label shape (n,); gmm object.
    '''
    unary_scale_factor = unary_scale_factor
    label_cost = label_cost
    algorithm = algorithm
    smooth_factor = smooth_factor
    gmm=gmm
#     a = count.copy() 
#     if sum(a>1)/len(count) <= 0.1 and sum(a>1)<=30:             ###  1-1, 0.25 can modify 
#         np.place(a, a==0, (np.random.rand(sum(a==0))*0.25)) # using 0.1 gives layer 4 300; 0.25 gives 150; 0.5 gives 80?
#         gmm = find_mixture_2(a)       
#     else:
#         a=a[a>0]
#         gmm = find_mixture(a)
    
    if profile==False:
        unary_cost = compute_unary_cost_simple(count,  gmm,  unary_scale_factor)
    else:
        unary_cost = compute_unary_cost_simple_profile(count, gmm, unary_scale_factor)
    
    pairwise_cost = compute_pairwise_cost(gmm.means_.shape[0], smooth_factor)
    edges = cellGraph[:,0:2].astype(np.int32)
    labels = pygco.cut_from_graph(edges, unary_cost,
                                                 pairwise_cost.astype(np.int32), np.int32(label_cost))
#    energy = compute_energy(unary_cost, pairwise_cost, edges, labels)

    return labels
Example #18
0
    def __multiscale_gc(self):  # , pyed):
        """
        In first step is performed normal GC.
        Second step construct finer grid on edges of segmentation from first
        step.
        There is no option for use without `use_boundary_penalties`
        """
        deb = False
        # deb = True
        # import py3DSeedEditor as ped

        from PyQt4.QtCore import pyqtRemoveInputHook
        pyqtRemoveInputHook()
        import scipy
        import scipy.ndimage
        logger.debug('performing multiscale_gc')
# default parameters
        sparams_lo = {
            'boundary_dilatation_distance': 2,
            'block_size': 6,
            'use_boundary_penalties': True,
            'boundary_penalties_weight': 1,
            'tile_zoom_constant': 1
        }

        sparams_lo.update(self.segparams)
        sparams_hi = copy.copy(sparams_lo)
        sparams_lo['boundary_penalties_weight'] = (
                sparams_lo['boundary_penalties_weight'] * 
                sparams_lo['block_size'])
        self.segparams = sparams_lo

# step 1:  low res GC
        hiseeds = self.seeds
        # ms_zoom = 4  # 0.125 #self.segparams['scale']
        ms_zoom = self.segparams['block_size']
        # loseeds = pyed.getSeeds()
        # logger.debug("msc " + str(np.unique(hiseeds)))
        loseeds = self.__seed_zoom(hiseeds, ms_zoom)

        area_weight = 1
        hard_constraints = True

        self.seeds = loseeds
        self.voxels1 = self.img[self.seeds == 1]
        self.voxels2 = self.img[self.seeds == 2]
        # self.voxels1 = pyed.getSeedsVal(1)
        # self.voxels2 = pyed.getSeedsVal(2)

        img_orig = self.img

        self.img = scipy.ndimage.interpolation.zoom(img_orig, 1.0 / ms_zoom,
                                                    order=0)

        self.make_gc()
        logger.debug(
            'segmentation - max: %d min: %d' % (
                np.max(self.segmentation),
                np.min(self.segmentation)
            )
        )

        seg = 1 - self.segmentation.astype(np.int8)
        # in seg is now stored low resolution segmentation
# step 2: discontinuity localization
        # self.segparams = sparams_hi
        segl = scipy.ndimage.filters.laplace(seg, mode='constant')
        logger.debug(str(np.max(segl)))
        logger.debug(str(np.min(segl)))
        segl[segl != 0] = 1
        logger.debug(str(np.max(segl)))
        logger.debug(str(np.min(segl)))
        # scipy.ndimage.morphology.distance_transform_edt
        boundary_dilatation_distance = self.segparams[
            'boundary_dilatation_distance']
        seg = scipy.ndimage.morphology.binary_dilation(
            seg,
            np.ones([
                (boundary_dilatation_distance * 2) + 1,
                (boundary_dilatation_distance * 2) + 1,
                (boundary_dilatation_distance * 2) + 1
            ])
        )
        if deb:
            import sed3
            pd = sed3.sed3(seg)  # ), contour=seg)
            pd.show()
#        segzoom = scipy.ndimage.interpolation.zoom(seg.astype('float'), zoom,
#                                                order=0).astype('int8')
# step 3: indexes of new dual graph
        msinds = self.__multiscale_indexes(seg, img_orig.shape, ms_zoom)
        logger.debug('multiscale inds ' + str(msinds.shape))
        # if deb:
        #     import sed3
        #     pd = sed3.sed3(msinds, contour=seg)
        #     pd.show()

        # intensity values for indexes
        # @TODO compute average values for low resolution
        ms_img = img_orig

        # @TODO __ms_create_nlinks , use __ordered_values_by_indexes
        # import pdb; pdb.set_trace() # BREAKPOINT
        # pyed.setContours(seg)

        # there is need to set correct weights between neighbooring pixels
        # this is not nice hack.
        # @TODO reorganise segparams and create_nlinks function
        self.img = img_orig  # not necessary
        orig_shape = img_orig.shape

        def local_ms_npenalty(x):
            return self.__ms_npenalty_fcn(x, seg, ms_zoom, orig_shape)
            # return self.__uniform_npenalty_fcn(orig_shape)
        # ms_npenalty_fcn = lambda x: self.__ms_npenalty_fcn(x, seg, ms_zoom,
        #                                                    orig_shape)


# here are not unique couples of nodes
        nlinks_not_unique = self.__create_nlinks(
            ms_img,
            msinds,
            # boundary_penalties_fcn=ms_npenalty_fcn
            boundary_penalties_fcn=local_ms_npenalty
        )

# get unique set
        # remove repetitive link from one pixel to another
        nlinks = np.array(
            [list(x) for x in set(tuple(x) for x in nlinks_not_unique)]
        )
        # now remove cycle link
        nlinks = np.array([line for line in nlinks if line[0] != line[1]])



        # import ipdb; ipdb.set_trace() #  noqa BREAKPOINT
# tlinks - indexes, data_merge
        ms_values_lin = self.__ordered_values_by_indexes(img_orig, msinds)
        seeds = hiseeds
        # seeds = pyed.getSeeds()
        # if deb:
        #     import sed3
        #     se = sed3.sed3(seeds)
        #     se.show()
        ms_seeds_lin = self.__ordered_values_by_indexes(seeds, msinds)
        # logger.debug("unique seeds " + str(np.unique(seeds)))
        # logger.debug("unique seeds " + str(np.unique(ms_seeds_lin)))

        unariesalt = self.__create_tlinks(ms_values_lin,
                                          self.voxels1, self.voxels2,
                                          ms_seeds_lin,
                                          area_weight, hard_constraints)

# create potts pairwise
        # pairwiseAlpha = -10
        pairwise = -(np.eye(2) - 1)
        pairwise = (self.segparams['pairwise_alpha'] * pairwise
                    ).astype(np.int32)

        # print 'data shape ', img_orig.shape
        # print 'nlinks sh ', nlinks.shape
        # print 'tlinks sh ', unariesalt.shape

    # Same functionality is in self.seg_data()
        result_graph = pygco.cut_from_graph(
            nlinks,
            unariesalt.reshape(-1, 2),
            pairwise
        )

# probably not necessary
#        del nlinks
#        del unariesalt

        # print "unaries %.3g , %.3g" % (np.max(unariesalt),np.min(unariesalt))
        # @TODO get back original data
        # result_labeling = result_graph.reshape(data.shape)
        result_labeling = result_graph[msinds]
        # import py3DSeedEditor
        # ped = py3DSeedEditor.py3DSeedEditor(result_labeling)
        # ped.show()
        self.segmentation = result_labeling
Example #19
0
# plt.show()

#   pairwise term
alpha = 50
pairwise = - alpha * np.eye(n_components, dtype=np.int32)

print 'deriving graph edges...'
# use the general graph algorithm
# first, we construct the grid graph
inds = np.arange(im.size).reshape(im.shape)
horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
edges = np.vstack([horz, vert]).astype(np.int32)

# we flatten the unaries
result_graph = cut_from_graph(edges, unaries.reshape(-1, n_components), pairwise)
res = result_graph.reshape(im.shape)

plt.figure()
plt.subplot(121), plt.imshow(im, 'gray'), plt.title('input image')
plt.subplot(122), plt.imshow(res, 'gray'), plt.title('segmentation')
# plt.show()

# plotting results
color_iter = itertools.cycle(['r', 'g', 'b', 'c', 'm', 'y', 'k'])
x = np.arange(0, 255, 0.1)
hist, bins = skiexp.histogram(pixs, nbins=256)

plt.figure()
plt.subplot(211), plt.plot(bins, hist)
ax = plt.axis()
Example #20
0
    def sparse_approximation(self):
        '''
        Use a few manifolds to sparsely approximate the pareto front by graph-cut, see section 6.4.
        Output:
            labels: the optimized labels (manifold index) for each non-empty cell (the cells also contain the corresponding labeled sample), shape = (n_label,)
            approx_x: the labeled design samples, shape = (n_label, n_var)
            approx_y: the labeled performance values, shape = (n_label, n_obj)
        '''
        # update patch ids, remove non-existing ids previously removed from buffer
        mapping = {}
        patch_id_count = 0
        for cell_id in range(self.cell_num):
            if self.buffer_patch_id[cell_id] == []: continue
            curr_patches = self.buffer_patch_id[cell_id]
            for i in range(len(curr_patches)):
                if curr_patches[i] not in mapping:
                    mapping[curr_patches[i]] = patch_id_count
                    patch_id_count += 1
                self.buffer_patch_id[cell_id][i] = mapping[curr_patches[i]]

        # construct unary and pairwise energy (cost) matrix for graph-cut
        # NOTE: delta_b should be set properly
        valid_cells = np.where([
            self.buffer_dist[cell_id] != [] for cell_id in range(self.cell_num)
        ])[0]  # non-empty cells
        n_node = len(valid_cells)
        n_label = patch_id_count
        unary_cost = self.C_inf * np.ones((n_node, n_label))
        pairwise_cost = -self.C_inf * np.eye(n_label)

        for i, idx in enumerate(valid_cells):
            patches, distances = np.array(self.buffer_patch_id[idx]), np.array(
                self.buffer_dist[idx])
            min_dist = np.min(distances)
            unary_cost[i, patches] = np.minimum(
                (distances - min_dist) / self.delta_b, self.C_inf)

        # get edge information (graph structure)
        edges = self._get_graph_edges(valid_cells)

        # NOTE: pygco only supports int32 as input, due to potential numerical error
        edges, unary_cost, pairwise_cost, label_cost = \
            edges.astype(np.int32), unary_cost.astype(np.int32), pairwise_cost.astype(np.int32), np.int32(self.label_cost)

        # do graph-cut, optimize labels for each valid cell
        labels_opt = cut_from_graph(edges, unary_cost, pairwise_cost,
                                    label_cost)

        # find corresponding design and performance values of optimized labels for each valid cell
        approx_xs, approx_ys = [], []
        labels = [
        ]  # for a certain cell, there could be no sample belongs to that label, probably due to the randomness of sampling or improper energy definition
        for idx, label in zip(valid_cells, labels_opt):
            for cell_patch_id, cell_x, cell_y in zip(self.buffer_patch_id[idx],
                                                     self.buffer_x[idx],
                                                     self.buffer_y[idx]):
                # since each buffer element array is sorted based on distance to origin
                if cell_patch_id == label:
                    approx_xs.append(cell_x)
                    approx_ys.append(cell_y)
                    labels.append(label)
                    break
            else:  # TODO: check
                approx_xs.append(self.buffer_x[idx][0])
                approx_ys.append(self.buffer_y[idx][0])
                labels.append(label)
        approx_xs, approx_ys = np.array(approx_xs), np.array(approx_ys)

        # NOTE: uncomment code below to show visualization of graph cut
        # import matplotlib.pyplot as plt
        # from matplotlib import cm
        # cmap = cm.get_cmap('tab20', patch_id_count)
        # fig, axs = plt.subplots(1, 2, sharex=True, sharey=True)
        # buffer_ys = np.vstack([np.vstack(cell_y) for cell_y in self.buffer_y if cell_y != []])
        # buffer_patch_ids = np.concatenate([cell_patch_id for cell_patch_id in np.array(self.buffer_patch_id)[valid_cells]])
        # colors = [cmap(patch_id) for patch_id in buffer_patch_ids]
        # axs[0].scatter(*buffer_ys.T, s=10, c=colors)
        # axs[0].set_title('Before graph cut')
        # colors = [cmap(label) for label in labels]
        # axs[1].scatter(*approx_ys.T, s=10, c=colors)
        # axs[1].set_title('After graph cut')
        # fig.suptitle(f'Sparse approximation, # patches: {patch_id_count}, # families: {len(np.unique(labels))}')
        # plt.show()

        return labels, approx_xs, approx_ys
def run_mrf(data_o, params):
    # slice_idx = self.params['slice_idx']
    alpha = params['alpha']
    beta = params['beta']
    # hypo_lab = params['hypo_label']
    # hyper_lab = params['hyper_label']

    # zooming the data
    print 'rescaling data ...',
    if params['zoom']:
        data = data_zoom(data_o.data, data_o.voxel_size, params['working_voxel_size_mm'])
        mask = data_zoom(data_o.mask, data_o.voxel_size, params['working_voxel_size_mm'])
    else:
        data = tools.resize3D(data_o.data, params['scale'])
        mask = np.round(tools.resize3D(data_o.mask, params['scale'])).astype(np.bool)
    print 'ok'

    # smoothing the data
    # data = tools.smoothing_tv(data, weight=5, output_as_uint8=False, sliceId=0)
    # data = tools.smoothing_median(data, radius=3, mask=mask, sliceId=0)
    # np.save('data.npy', data)
    # data = data.astype(np.uint8)

    # calculating intensity models if necesarry
    print 'estimating color models ...'
    if data_o.models is None:
        data_o.models = calculate_intensity_models(data, mask, params)
        print 'ok'
    else:
        print 'already done'

    # mask = tools.dilating3D(mask, selem=skimor.disk(1), slicewise=True, sliceId=0)
    # mask = tools.eroding3D(mask, selem=skimor.disk(5), slicewise=True, sliceId=0)

    print 'calculating unary potentials ...',
    # self.status_bar.showMessage('Calculating unary potentials...')
    # create unaries
    # # as we convert to int, we need to multipy to get sensible values
    # unaries = (1 * np.dstack([unaries, -unaries]).copy("C")).astype(np.int32)
    # data_o.models = get_fuzzy_models(data, mask, n_clusters=3)
    unaries = beta * get_unaries(data, mask, data_o.models, params)
    # mems, cntrs, fpc = fcm(data, mask, n_clusters=3)
    # unaries = np.dstack((mems[0,...].reshape(-1, 1), mems[1,...].reshape(-1, 1), mems[2,...].reshape(-1, 1)))
    # unaries = (beta * 100 * unaries).astype(np.int32)

    # unaries, mask = add_heal_border_to_unaries(unaries, mask)
    # np.save('unaries.npy', unaries)
    # Viewer_3D(unaries[:,:,0].reshape(data.shape)).show()

    n_labels = unaries.shape[2]
    print 'ok'

    print 'calculating pairwise potentials ...',
    # self.status_bar.showMessage('Calculating pairwise potentials...')
    # create potts pairwise
    pairwise = -alpha * np.eye(n_labels, dtype=np.int32)
    print 'ok'

    print 'deriving graph edges ...',
    # self.status_bar.showMessage('Deriving graph edges...')
    # use the gerneral graph algorithm
    # first, we construct the grid graph
    inds = np.arange(data.size).reshape(data.shape)
    if data.ndim == 2:
        horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
        vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
        edges = np.vstack([horz, vert]).astype(np.int32)
    elif data.ndim == 3:
        horz = np.c_[inds[:, :, :-1].ravel(), inds[:, :, 1:].ravel()]
        vert = np.c_[inds[:, :-1, :].ravel(), inds[:, 1:, :].ravel()]
        dept = np.c_[inds[:-1, :, :].ravel(), inds[1:, :, :].ravel()]
        edges = np.vstack([horz, vert, dept]).astype(np.int32)
    # deleting edges with nodes outside the mask
    nodes_in = np.ravel_multi_index(np.nonzero(mask), data.shape)
    rows_inds = np.in1d(edges, nodes_in).reshape(edges.shape).sum(axis=1) == 2
    edges = edges[rows_inds, :]
    print 'ok'

    # plt.show()

    # un = unaries[:, :, 0].reshape(data_o.shape)
    # un = unaries[:, :, 1].reshape(data_o.shape)
    # un = unaries[:, :, 2].reshape(data_o.shape)
    # py3DSeedEditor.py3DSeedEditor(un).show()

    print 'calculating graph cut ...',
    # self.status_bar.showMessage('Calculating graph cut...')
    result_graph = pygco.cut_from_graph(edges, unaries.reshape(-1, n_labels), pairwise)
    labels = result_graph.reshape(data.shape) + 1  # +1 to shift the first class to label number 1
    # np.save('labels.npy', result_graph.reshape(data.shape))

    labels = np.where(mask, labels, params['bgd_label'])

    # mask = tools.eroding3D(mask, selem=skimor.disk(2), slicewise=True, sliceId=0)
    # labels *= mask

    # zooming to the original size
    if params['zoom']:
        data_o.labels = zoom_to_shape(labels, data_o.orig_shape)
    else:
        data_o.labels = np.round(tools.resize3D(labels, shape=data_o.orig_shape)).astype(np.int64)

    print 'ok'
    # self.status_bar.showMessage('Done')

    # debug visualization
    # self.viewer = Viewer_3D.Viewer_3D(self.res, range=True)
    # self.viewer.show()

    print 'extracting objects ...',
    # self.status_bar.showMessage('Extracting objects ...'),
    labels_tmp = np.where(data_o.labels == params['healthy_label'], params['bgd_label'], data_o.labels)  # because we can set only one label as bgd
    data_o.objects = skimea.label(labels_tmp, background=params['bgd_label'])
    data_o.lesions = Lesion.extract_lesions(data_o.objects, data_o.data, params['voxels2ml_k'])
    # self.status_bar.showMessage('Done')
    print 'ok'
Example #22
0
def obtain_graph_cuts_segmentation(structure_posterior_energy, \
     not_structure_posterior_energy):
    """Obtains the graph cuts segmentation for a structure given the posterior 
       energies.  
    
    Parameters
    ----------
    structure_posterior_energy: A float array with shape (L, M, N) 
            representing the posterior energies for the structure of interest. 
            (source) 
    not_structure_posterior_energy :  A float array with shape (L, M, N) 
            representing the posterior energies for not being the structure
            of interest. (sink)
        ...
        
    Returns
    -------
    label_map : array, shape (L, M, N)
        Segmented image with labels adhering to CIP conventions
    """

    length = np.shape(structure_posterior_energy)[0]
    width = np.shape(structure_posterior_energy)[1]
    if (np.size(np.shape(structure_posterior_energy)[1]) == 3):
        num_slices = np.shape(structure_posterior_energy)[2]
    else:
        num_slices = 1

    numNodes = length * width
    segmented_image = np.zeros((length, width, num_slices), dtype=np.int32)

    for slice_num in range(0, num_slices):
        print("graph cut slice" + str(slice_num))
        print(np.shape(structure_posterior_energy))

        source_slice_temp = structure_posterior_energy[:, :].squeeze().astype(
            np.int32)  # mode='c'
        sink_slice_temp = not_structure_posterior_energy[:, :].squeeze(
        ).astype(np.int32)

        m_shape = np.shape(source_slice_temp)
        #source_slice = np.memmap(source_slice_temp, dtype='int32', mode='c', shape=(m_shape[0],m_shape[1]))
        #sink_slice = np.memmap(sink_slice_temp, dtype='int32', mode='c', shape=(m_shape[0],m_shape[1]))

        source_slice = np.reshape(source_slice_temp,
                                  np.shape(source_slice_temp),
                                  order='C')
        sink_slice = np.reshape(sink_slice_temp,
                                np.shape(sink_slice_temp),
                                order='C')
        #source_slice = structure_posterior_energy[:,:].squeeze().astype(np.int32) # mode='c'
        #sink_slice = not_structure_posterior_energy[:,:].squeeze().astype(np.int32)

        #source_slice = structure_posterior_energy[:,:,slice_num: \
        #   (slice_num+1)].squeeze().astype(np.int32)
        #sink_slice = not_structure_posterior_energy[:,:,slice_num: \
        #   (slice_num+1)].squeeze().astype(np.int32)

        imageIndexArray =  np.arange(numNodes).reshape(np.shape( \
           source_slice)[0], np.shape(source_slice)[1])

        #Adding neighbourhood terms
        inds = np.arange(imageIndexArray.size).reshape(imageIndexArray.shape)
        #goes from [[0,1,...numcols-1],[numcols, ...],..[.., num_elem-1]]
        horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
        #all rows, not last col make to 1d
        vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
        #all rows, not first col, make to 1d
        edges = np.vstack([horz, vert]).astype(np.int32)
        #horz is first element, vert is
        theweights = np.ones(
            (np.shape(edges))).astype(np.int32) * 30  #*50#*150 ##*180
        edges = np.hstack((edges, theweights))[:, 0:3].astype(np.int32)
        #stack the weight value hor next to edge indeces

        ##    #3rd order neighbours, good for lung
        horz = np.c_[inds[:, :-2].ravel(), inds[:, 2:].ravel()]
        #all rows, not last col make to 1d
        vert = np.c_[inds[:-2, :].ravel(), inds[2:, :].ravel()]
        #all rows, not first col, make to 1d
        edges2 = np.vstack([horz, vert]).astype(np.int32)
        #horz is first element, vert is
        theweights2 = np.ones((np.shape(edges2))).astype(np.int32) * 5  #*30
        edges2 = np.hstack((edges2, theweights2))[:, 0:3].astype(np.int32)

        edges_temp = np.vstack([edges, edges2]).astype(np.int32)
        edges = np.reshape(edges_temp, np.shape(edges_temp), order='C')
        pairwise_cost = np.array([[0, 125], [125, 0]],
                                 dtype=np.int32,
                                 order='C')

        energies_temp = np.dstack((np.array(source_slice).astype(np.int32).flatten(), \
        np.array(sink_slice).astype(np.int32).flatten())).squeeze()

        energies = np.ascontiguousarray(
            np.reshape(energies_temp, np.shape(energies_temp), order='C'))
        segmented_slice = cut_from_graph(edges, energies, pairwise_cost, 3, \
          'expansion')
        segmented_image[:, :,
                        slice_num] = segmented_slice.reshape(length, width)

    return segmented_image
Example #23
0
    def segment_edge_cut(self):
        # noinspection PyUnresolvedReferences
        from pygco import cut_from_graph

        height = self.image.shape[0]
        width = self.image.shape[1]

        # first, we construct the grid graph
        # inds is a matrix of cell indices
        inds = np.arange(height * width).reshape(height, width)
        # list of all horizontal and vertical edges
        horizontal_edges = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
        vertical_edges = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
        # concatenate both lists
        edges = np.vstack([horizontal_edges, vertical_edges]).astype(np.int32)

        # the edge weight multiplies the logarithm of the probability, this is the same as potentiating the probability
        # and renormalizing
        def effective_probability(probability, weight):
            return probability**weight / (probability**weight +
                                          (1 - probability)**weight)

        depth = self.feature_images['depth'].reshape(-1)
        depth[depth == -1] = np.nan

        self.edge_depth_diff = np.abs(depth[edges[:, 0]] - depth[edges[:, 1]])

        weights = np.ones([edges.shape[0], 1])  # weight is 1 for nan
        depth_diff_thres = 0.02  # in m

        # replace nans with threshold to prevent comparing to nan warnings
        self.edge_depth_diff[np.isnan(self.edge_depth_diff)] = depth_diff_thres
        smooth_depth_edges = self.edge_depth_diff < depth_diff_thres
        sharp_depth_edges = self.edge_depth_diff > depth_diff_thres

        weights[
            smooth_depth_edges] = 2  # effective for 0.95 + weight 2 -> 0.9972375
        weights[sharp_depth_edges] = 0

        # add this for displaying the depth edges
        self.depth_edge_image = np.zeros(height * width)
        self.depth_edge_image[edges[smooth_depth_edges].reshape(-1)] = -1
        self.depth_edge_image[edges[sharp_depth_edges].reshape(-1)] = 1
        self.depth_edge_image = self.depth_edge_image.reshape(height, width)

        edges = np.hstack([edges, weights])

        # compute potentials (log of probabilities)
        unaries = -np.log(
            np.array([
                np.clip(self.posterior_images[o], a_min=0.01, a_max=1.0)
                for o in self.candidate_objects
            ])).transpose((1, 2, 0))
        num_labels = unaries.shape[2]
        p_same_label = 0.95
        pairwise = -np.log(1 - p_same_label) * (
            1 - np.eye(num_labels)) - np.log(p_same_label) * np.eye(num_labels)

        k = 10  # scaling factor for potentials to reduce aliasing because the potentials need to be converted to integers

        unaries_c = np.copy((k * unaries).astype('int32'),
                            order='C').reshape(-1, num_labels)
        pairwise_c = np.copy((k * pairwise).astype('int32'), order='C')
        edges_c = edges.astype('int32')
        self.segmentation = cut_from_graph(edges_c, unaries_c,
                                           pairwise_c).reshape(height, width)
                        else:
                            beta = 1 + np.linalg.norm(
                                np.dot(normals[i_node, 0:3], normals[i_nei,
                                                                     0:3]))
                            edges = np.concatenate(
                                (edges,
                                 np.array([
                                     i_node, i_nei,
                                     -beta * math.log10(theta / np.pi) * phi
                                 ]).reshape(1, 3)),
                                axis=0)
            edges = np.delete(edges, 0, 0)
            edges[:, 2] *= lambda_c * round_factor
            edges = edges.astype(np.int32)

            refine_labels = cut_from_graph(edges, unaries, pairwise)
            refine_labels = refine_labels.reshape([-1, 1])

            # output refined result
            mesh2 = Easy_Mesh()
            mesh2.cells = mesh_d.cells
            mesh2.update_cell_ids_and_points()
            mesh2.cell_attributes['Label'] = refine_labels
            mesh2.to_vtp(
                os.path.join(
                    output_path,
                    '{}_d_predicted_refined_pygco.vtp'.format(i_sample[:-4])))

            # upsampling
            print('\tUpsampling...')
            if mesh.cells.shape[0] > 100000:
Example #25
0
    def run(self, resize=True):
        #----  rescaling  ----
        if resize and self.scale != 0:
            self.img = tools.resize3D(self.img_orig, self.scale, sliceId=0)
            self.seeds = tools.resize3D(self.seeds_orig, self.scale, sliceId=0)
            self.mask = tools.resize3D(self.mask_orig, self.scale, sliceId=0)
            # for i, (im, seeds, mask) in enumerate(zip(self.img_orig, self.seeds_orig, self.mask_orig)):
            #     self.img[i, :, :] = cv2.resize(im, (0,0), fx=self.scale, fy=self.scale, interpolation=cv2.INTER_NEAREST)
            #     self.seeds[i, :, :] = cv2.resize(seeds, (0,0),  fx=self.scale, fy=self.scale, interpolation=cv2.INTER_NEAREST)
            #     self.mask[i, :, :] = cv2.resize(mask, (0,0),  fx=self.scale, fy=self.scale, interpolation=cv2.INTER_NEAREST)
        # else:
        #     self.img = self.img_orig
        #     self.seeds = self.seeds_orig
        self.n_slices, self.n_rows, self.n_cols = self.img.shape

        #----  calculating intensity models  ----
        # if self.unaries is None:
        if self.models is None:
            self._debug('calculating intensity models ...', False)
            # self.models = self.calc_intensity_models()
            self.models = self.calc_models()
            self._debug('done', True)

        #----  creating unaries  ----
        if self.unaries is None:
            self._debug('calculating unary potentials ...', False)
            self.unaries = self.beta * self.get_unaries()
            self._debug('done', True)

        #----  create potts pairwise  ----
        if self.pairwise is None:
            self._debug('calculating pairwise potentials ...', False)
            # self.pairwise = - self.alpha * np.eye(self.n_objects, dtype=np.int32)
            self.set_pairwise()
            self._debug('done', True)

        #----  deriving graph edges  ----
        self._debug('deriving graph edges ...', False)
        # use the gerneral graph algorithm
        # first, we construct the grid graph
        # inds = np.arange(self.n_rows * self.n_cols).reshape(self.img.shape)
        # horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
        # vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
        # self.edges = np.vstack([horz, vert]).astype(np.int32)
        inds = np.arange(self.img.size).reshape(self.img.shape)
        if self.img.ndim == 2:
            horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
            vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
            self.edges = np.vstack([horz, vert]).astype(np.int32)
        elif self.img.ndim == 3:
            horz = np.c_[inds[:, :, :-1].ravel(), inds[:, :, 1:].ravel()]
            vert = np.c_[inds[:, :-1, :].ravel(), inds[:, 1:, :].ravel()]
            dept = np.c_[inds[:-1, :, :].ravel(), inds[1:, :, :].ravel()]
            self.edges = np.vstack([horz, vert, dept]).astype(np.int32)
        # deleting edges with nodes outside the mask
        nodes_in = np.ravel_multi_index(np.nonzero(self.mask), self.img.shape)
        rows_inds = np.in1d(self.edges, nodes_in).reshape(
            self.edges.shape).sum(axis=1) == 2
        self.edges = self.edges[rows_inds, :]
        self._debug('done', True)

        #----  calculating graph cut  ----
        self._debug('calculating graph cut ...', False)
        # we flatten the unaries
        result_graph = pygco.cut_from_graph(
            self.edges, self.unaries.reshape(-1, self.n_objects),
            self.pairwise)
        self.labels = result_graph.reshape(self.img.shape)
        self._debug('done', True)

        #----  zooming to the original size  ----
        if resize and self.scale != 0:
            # self.labels_orig = cv2.resize(self.labels, (0,0),  fx=1. / self.scale, fy= 1. / self.scale, interpolation=cv2.INTER_NEAREST)
            self.labels_orig = tools.resize3D(self.labels,
                                              1. / self.scale,
                                              sliceId=0)
        else:
            self.labels_orig = self.labels

        self._debug('----------', True)
        self._debug('segmentation done', True)

        # self.show_slice(0)

        # plt.figure()
        # plt.subplot(221), plt.imshow(self.img_orig[0, :, :], 'gray', interpolation='nearest'), plt.title('input image')
        # plt.subplot(222), plt.imshow(self.seeds_orig[0, :, :], interpolation='nearest')
        # # plt.hold(True)
        # # seeds_v = np.nonzero(self.seeds)
        # # for i in range(len(seeds_v[0])):
        # #     seed = (seeds_v[0][i], seeds_v[1][i])
        # #     if self.seeds[seed]
        # #
        # # plt.plot
        # plt.title('seeds')
        # plt.subplot(223), plt.imshow(self.labels, interpolation='nearest'), plt.title('segmentation')
        # plt.subplot(224), plt.imshow(skiseg.mark_boundaries(self.img_orig, self.labels), interpolation='nearest'), plt.title('segmentation')
        # plt.show()

        return self.labels_orig
    def run(self):
        # slice_idx = self.params['slice_idx']
        alpha = self.params['alpha']
        beta = self.params['beta']
        hypo_lab = self.params['hypo_label']
        hyper_lab = self.params['hyper_label']

        # if not fname:
        #     _, self.data, self.mask = self.load_data(slice_idx)
        # else:
        #     self.data, self.mask, self.voxel_size = self.load_pickle_data(self.fname, self.params, slice_idx)
        # self.data = self.data.astype(np.uint8)

        # TumorVisualiser.run(data, mask, params['healthy_label'], params['hypo_label'], params['hyper_label'], slice_axis=0, disp_smoothed=True)

        # print 'estimating number of clusters ...',
        # print '\tcurrently switched off'
        # d = scindiint.zoom(data_o, 0.5)
        # m = skitra.resize(mask, np.array(mask.shape) * 0.5).astype(np.bool)
        # ints = d[np.nonzero(m)]
        # ints = ints.reshape((ints.shape[0], 1))
        # for i in range(2, 5):
        #     kmeans_model = KMeans(n_clusters=i, n_init=1).fit(ints)
        #     labels = kmeans_model.labels_
        #
        #     sc = metrics.silhouette_score(ints, labels, metric='euclidean')
        #     print '\tn_clusters = %i, score = %1.3f (best score=1, worse score=-1)' % (i, sc)

        # data_o = cv2.imread('/home/tomas/Dropbox/images/medicine/hypodense_bad2.png', 0).astype(np.float)

        # data_s = skifil.gaussian_filter(data_o, sigma)
        #
        # #imd = np.absolute(im - ims)
        # data_d = data_o - data_s
        #
        # data_d = np.where(data_d < 0, 0, data_d)

        # zooming the data
        print 'rescaling data ...',
        if self.params['zoom']:
            self.actual_data.data = self.data_zoom(self.actual_data.data, self.actual_data.voxel_size, self.params['working_voxel_size_mm'])
            self.actual_data.mask = self.data_zoom(self.actual_data.mask, self.actual_data.voxel_size, self.params['working_voxel_size_mm'])
        else:
            data = tools.resize3D(self.actual_data.data, self.params['scale'], sliceId=0)
            mask = tools.resize3D(self.actual_data.mask, self.params['scale'], sliceId=0)
        print 'ok'
        # data = data.astype(np.uint8)

        # calculating intensity models if necesarry
        print 'estimating color models ...'
        if not self.models:
            self.models = self.calculate_intensity_models(data, mask)
            print 'ok'
        else:
            print 'already done'

        print 'calculating unary potentials ...',
        self.status_bar.showMessage('Calculating unary potentials...')
        # create unaries
        # unaries = data_d
        # # as we convert to int, we need to multipy to get sensible values
        # unaries = (1 * np.dstack([unaries, -unaries]).copy("C")).astype(np.int32)
        self.unaries = beta * self.get_unaries(data, mask, self.models, self.params)
        n_labels = self.unaries.shape[2]
        print 'ok'

        print 'calculating pairwise potentials ...',
        self.status_bar.showMessage('Calculating pairwise potentials...')
        # create potts pairwise
        self.pairwise = -alpha * np.eye(n_labels, dtype=np.int32)
        print 'ok'

        print 'deriving graph edges ...',
        self.status_bar.showMessage('Deriving graph edges...')
        # use the gerneral graph algorithm
        # first, we construct the grid graph
        inds = np.arange(data.size).reshape(data.shape)
        if data.ndim == 2:
            horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
            vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
            self.edges = np.vstack([horz, vert]).astype(np.int32)
        elif data.ndim == 3:
            # horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()]
            # vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()]
            horz = np.c_[inds[:, :, :-1].ravel(), inds[:, :, 1:].ravel()]
            vert = np.c_[inds[:, :-1, :].ravel(), inds[:, 1:, :].ravel()]
            dept = np.c_[inds[:-1, :, :].ravel(), inds[1:, :, :].ravel()]
            self.edges = np.vstack([horz, vert, dept]).astype(np.int32)
        # deleting edges with nodes outside the mask
        nodes_in = np.ravel_multi_index(np.nonzero(mask), data.shape)
        rows_inds = np.in1d(self.edges, nodes_in).reshape(self.edges.shape).sum(axis=1) == 2
        self.edges = self.edges[rows_inds, :]
        print 'ok'

        # plt.show()

        # un = unaries[:, :, 0].reshape(data_o.shape)
        # un = unaries[:, :, 1].reshape(data_o.shape)
        # un = unaries[:, :, 2].reshape(data_o.shape)
        # py3DSeedEditor.py3DSeedEditor(un).show()

        print 'calculating graph cut ...',
        self.status_bar.showMessage('Calculating graph cut...')
        # we flatten the unaries
        # result_graph = pygco.cut_from_graph(edges, unaries.reshape(-1, 2), pairwise)
        # print 'tu: ', unaries.reshape(-1, n_labels).shape
        result_graph = pygco.cut_from_graph(self.edges, self.unaries.reshape(-1, n_labels), self.pairwise)
        labels = result_graph.reshape(data.shape) + 1  # +1 to shift the first class to label number 1

        labels = np.where(mask, labels, self.params['bgd_label'])

        # zooming to the original size
        if self.params['zoom']:
            self.actual_data.labels = self.zoom_to_shape(labels, self.actual_data.orig_shape)
        else:
            # self.actual_data.labels = tools.resize3D(labels, scale=1. / self.params['scale'], sliceId=0)
            # self.actual_data.labels2 = skitra.resize(labels, self.actual_data.orig_shape, mode='nearest', preserve_range=True).astype(np.int64)
            self.actual_data.labels = tools.resize3D(labels, shape=self.actual_data.orig_shape, sliceId=0)#.astype(np.int64)

        print 'ok'
        self.status_bar.showMessage('Done')

        # debug visualization
        # self.viewer = Viewer_3D.Viewer_3D(self.res, range=True)
        # self.viewer.show()

        print 'extracting objects ...',
        self.status_bar.showMessage('Extracting objects ...'),
        labels_tmp = np.where(self.actual_data.labels == self.params['healthy_label'], self.params['bgd_label'], self.actual_data.labels)  # because we can set only one label as bgd
        self.actual_data.objects = skimea.label(labels_tmp, background=self.params['bgd_label'])
        self.actual_data.lesions = Lesion.extract_lesions(self.actual_data.objects, self.actual_data.data)
        # areas = [x.area for x in self.actual_data.lesions]
        self.status_bar.showMessage('Done')
        print 'ok'

        print 'initial filtration ...',
        self.objects_filtration(area=(self.params['min_area'], self.params['max_area']),
                                density=(self.params['min_density'], self.params['max_density']),
                                compactness=self.params['min_compactness'])
        print 'ok'
        self.status_bar.showMessage('Done')
def obtain_graph_cuts_segmentation(structure_posterior_energy, \
     not_structure_posterior_energy):
    """Obtains the graph cuts segmentation for a structure given the posterior 
       energies.  
    
    Parameters
    ----------
    structure_posterior_energy: A float array with shape (L, M, N) 
            representing the posterior energies for the structure of interest. 
            (source) 
    not_structure_posterior_energy :  A float array with shape (L, M, N) 
            representing the posterior energies for not being the structure
            of interest. (sink)
        ...
        
    Returns
    -------
    label_map : array, shape (L, M, N)
        Segmented image with labels adhering to CIP conventions
    """

    length = np.shape(structure_posterior_energy)[0];
    width = np.shape(structure_posterior_energy)[1];
    if (np.size(np.shape(structure_posterior_energy)[1]) == 3):
        num_slices = np.shape(structure_posterior_energy)[2];
    else:
        num_slices = 1 
        
    numNodes = length * width
    segmented_image = np.zeros((length, width, num_slices), dtype = np.int32)
    
    for slice_num in range(0, num_slices):
        print("graph cut slice" +str(slice_num))
        print(np.shape(structure_posterior_energy))

        source_slice_temp = structure_posterior_energy[:,:].squeeze().astype(np.int32) # mode='c' 
        sink_slice_temp = not_structure_posterior_energy[:,:].squeeze().astype(np.int32) 
        
        m_shape = np.shape(source_slice_temp)                
        #source_slice = np.memmap(source_slice_temp, dtype='int32', mode='c', shape=(m_shape[0],m_shape[1]))
        #sink_slice = np.memmap(sink_slice_temp, dtype='int32', mode='c', shape=(m_shape[0],m_shape[1]))
        
        source_slice = np.reshape(source_slice_temp, np.shape(source_slice_temp), order = 'C')
        sink_slice = np.reshape(sink_slice_temp, np.shape(sink_slice_temp),order = 'C')
        #source_slice = structure_posterior_energy[:,:].squeeze().astype(np.int32) # mode='c' 
        #sink_slice = not_structure_posterior_energy[:,:].squeeze().astype(np.int32) 

        #source_slice = structure_posterior_energy[:,:,slice_num: \
        #   (slice_num+1)].squeeze().astype(np.int32) 
        #sink_slice = not_structure_posterior_energy[:,:,slice_num: \
        #   (slice_num+1)].squeeze().astype(np.int32) 
           
        imageIndexArray =  np.arange(numNodes).reshape(np.shape( \
           source_slice)[0], np.shape(source_slice)[1])
 
        #Adding neighbourhood terms 
        inds = np.arange(imageIndexArray.size).reshape(imageIndexArray.shape) 
        #goes from [[0,1,...numcols-1],[numcols, ...],..[.., num_elem-1]]
        horz = np.c_[inds[:, :-1].ravel(), inds[:, 1:].ravel()] 
        #all rows, not last col make to 1d
        vert = np.c_[inds[:-1, :].ravel(), inds[1:, :].ravel()] 
        #all rows, not first col, make to 1d
        edges = np.vstack([horz, vert]).astype(np.int32) 
        #horz is first element, vert is 
        theweights = np.ones((np.shape(edges))).astype(np.int32)*30#*50#*150 ##*180
        edges = np.hstack((edges,theweights))[:,0:3].astype(np.int32) 
        #stack the weight value hor next to edge indeces
    
    ##    #3rd order neighbours, good for lung
        horz = np.c_[inds[:, :-2].ravel(), inds[:,2:].ravel()] 
        #all rows, not last col make to 1d
        vert = np.c_[inds[:-2, :].ravel(), inds[2:, :].ravel()] 
        #all rows, not first col, make to 1d
        edges2 = np.vstack([horz, vert]).astype(np.int32) 
        #horz is first element, vert is 
        theweights2 = np.ones((np.shape(edges2))).astype(np.int32)*5#*30
        edges2 = np.hstack((edges2,theweights2))[:,0:3].astype(np.int32)

        edges_temp = np.vstack([edges,edges2]).astype(np.int32)
        edges = np.reshape(edges_temp, np.shape(edges_temp), order = 'C')
        pairwise_cost = np.array([[0, 125], [125, 0]], dtype = np.int32, order = 'C')
    
        energies_temp = np.dstack((np.array(source_slice).astype(np.int32).flatten(), \
        np.array(sink_slice).astype(np.int32).flatten())).squeeze()

        energies = np.ascontiguousarray(np.reshape(energies_temp, np.shape(energies_temp), order = 'C'))
        segmented_slice = cut_from_graph(edges, energies, pairwise_cost, 3, \
          'expansion') 
        segmented_image[:,:,slice_num] = segmented_slice.reshape(length,width)

    return segmented_image
Example #28
0
    def set_data(self, data, voxels1, voxels2,
                 seeds=False,
                 hard_constraints=True,
                 area_weight=1):
        """
        Setting of data.
        You need set seeds if you want use hard_constraints.
        """
        # from PyQt4.QtCore import pyqtRemoveInputHook
        # pyqtRemoveInputHook()
        # import pdb; pdb.set_trace() # BREAKPOINT

        unariesalt = self.__create_tlinks(data, voxels1, voxels2, seeds,
                                          area_weight, hard_constraints)
#  některém testu  organ semgmentation dosahují unaries -15. což je podiné
# stačí vyhodit print před if a je to vidět
        logger.debug("unaries %.3g , %.3g" % (
            np.max(unariesalt), np.min(unariesalt)))
# create potts pairwise
        # pairwiseAlpha = -10
        pairwise = -(np.eye(2) - 1)
        pairwise = (self.segparams['pairwise_alpha'] * pairwise
                    ).astype(np.int32)
        # pairwise = np.array([[0,30],[30,0]]).astype(np.int32)
        # print pairwise

        self.iparams = {}

        if self.segparams['use_boundary_penalties']:
            sigma = self.segparams['boundary_penalties_sigma']
# set boundary penalties function
# Default are penalties based on intensity differences
            boundary_penalties_fcn = lambda ax: \
                self.boundary_penalties_array(axis=ax, sigma=sigma)
        else:
            boundary_penalties_fcn = None
        nlinks = self.__create_nlinks(data, 
                boundary_penalties_fcn=boundary_penalties_fcn)

        # print 'data shape ', data.shape
        # print 'nlinks sh ', nlinks.shape
        # print 'tlinks sh ', unariesalt.shape
# edges - seznam indexu hran, kteres spolu sousedi

# we flatten the unaries
        # result_graph = cut_from_graph(nlinks, unaries.reshape(-1, 2),
        # pairwise)
        result_graph = pygco.cut_from_graph(
            nlinks,
            unariesalt.reshape(-1, 2),
            pairwise
        )

# probably not necessary
#        del nlinks
#        del unariesalt

        # print "unaries %.3g , %.3g" % (np.max(unariesalt),
        # np.min(unariesalt))
        result_labeling = result_graph.reshape(data.shape)

        return result_labeling
Example #29
0
def propagationSegment(lastSegmentImageAddress,
                       nextOriginalImageAddress,
                       nextSegmentAddress,
                       algorithm="ffc",
                       boundingLength=18,
                       infiniteCost=100,
                       KCost=3):
    """
  the main function of propagation segmentation
  :param lastSegmentImageAddress: The address of the segment result of last image
  :param nextOriginalImageAddress: The address of the original image to be segmented in this layer
  :param nextSegmentAddress: The storage address of segmentation results
  :param algorithm: Algorithm category Fast-FineCut -- "ffc"  Waggoner -- "wag"
  :param boundingLength: the length of bounding region, default 18
  :param infiniteCost:  Default 100, refers to infinity
  :param KCost: K value of binary term, default 3
  :return: Return the segmentation result
  """

    # read the image
    tempLastSegment = cv.imread(lastSegmentImageAddress)
    if tempLastSegment is None:
        return "The last image's path is wrong"

    tempNextOriginal = cv.imread(nextOriginalImageAddress)
    if tempNextOriginal is None:
        return "The path of this layer's image is wrong"

    # Gets the number of horizontal and vertical coordinates of the image
    rowNumber = tempLastSegment.shape[0]
    colNumber = tempLastSegment.shape[1]

    # Convert the last image to a grayscale image if it is a color image
    lastSegment = np.zeros((rowNumber, colNumber))
    if tempLastSegment.ndim == 3:
        lastSegment = cv.cvtColor(tempLastSegment, cv.COLOR_BGR2GRAY)
    elif tempLastSegment.ndim == 2:
        lastSegment = tempLastSegment

    # Convert this layered image to a grayscale image if it is a color image
    nextOriginal = np.zeros((rowNumber, colNumber))
    if tempNextOriginal.ndim == 3:
        nextOriginal = cv.cvtColor(tempNextOriginal, cv.COLOR_BGR2GRAY)
    elif tempNextOriginal.ndim == 2:
        nextOriginal = tempNextOriginal

    if nextOriginal.shape != lastSegment.shape:
        return "Error! The image of the previous layer and the image of the layer is different in dimension."

    # Label the last image
    uniqueNum = np.unique(lastSegment)
    lastNumber = 0
    lastLabeled = np.zeros((rowNumber, colNumber))
    if len(uniqueNum) == 2:  # Binary image
        (lastLabeled, lastNumber) = label(lastSegment,
                                          background=255,
                                          neighbors=4,
                                          return_num=True)
        lastLabeled = reviseLabel(lastLabeled)
    elif len(uniqueNum) > 2:
        (lastLabeled, lastNumber) = label(lastSegment,
                                          neighbors=4,
                                          return_num=True)
    lastLabeled = lastLabeled.astype(np.int32)

    # Calculate the unary item unaryCostMatrix and bounding region
    unaryCostMatrix, boundingRegion = getUnaryCost(
        lastLabeled,
        lastSegment,
        return_boundingRegion=True,
        morphKernelNum=boundingLength,
        infiniteCost=infiniteCost)

    # Calculate the edgeImage required for the binary item
    blurredGaussian = cv.GaussianBlur(nextOriginal, (3, 3), 0)
    imgThreshMean = cv.adaptiveThreshold(blurredGaussian, 255,
                                         cv.ADAPTIVE_THRESH_MEAN_C,
                                         cv.THRESH_BINARY_INV, 5, 4)
    imgThreshMean = denoiseByArea(imgThreshMean, 300, neighbors=8)
    tempNextEdge = morphology.skeletonize(imgThreshMean / 255) * 255

    if algorithm == "ffc":
        # Fast-FineCut's binary term, use edgeImage
        binaryCostMatrix = getBinaryCostFromUnary(
            nextOriginal,
            lastSegment,
            lastLabeled,
            lastNumber,
            unaryCostMatrix,
            type="edgeImage",
            edgeOriginalImage=tempNextEdge,
            infiniteCost=infiniteCost,
            KCost=KCost)
    elif algorithm == "wag":
        # waggoner's binary term
        binaryCostMatrix = getBinaryCostByWaggoner(
            nextOriginal,
            lastSegment,
            lastLabeled,
            type="edgeImage",
            edgeOriginalImage=tempNextEdge,
            infiniteCost=infiniteCost)

    # calculate pairWiseMatrix
    pairWiseMatrix = getPairWiseMatrix(lastSegment, lastLabeled)

    # Graph-cut
    result_graph = cut_from_graph(binaryCostMatrix,
                                  unaryCostMatrix.reshape(-1, lastNumber),
                                  pairWiseMatrix,
                                  algorithm="swap")
    nextLabeled = result_graph.reshape(nextOriginal.shape)
    nextSegment = getEdgesFromLabel(nextLabeled)

    # Show the intermediate results
    # plt.subplot(231),plt.imshow(tempNextEdge,cmap="gray"),plt.title("nextEdges")
    # plt.subplot(232),plt.imshow(np.uint8(boundingRegion)),plt.title("boundingRegion")
    # #plt.subplot(232),plt.imshow(tempNextEdge,cmap="gray"),plt.title("nextEdges")
    # # plt.subplot(333),plt.imshow(unaryCost),plt.title("unaryCost")
    # plt.subplot(233),plt.imshow(addComparation(nextOriginal, binaryCostMatrix)),plt.title("binaryCostMatrix")
    # #plt.subplot(234),plt.imshow(ragShow),plt.title("rag")
    # plt.subplot(234),plt.imshow(nextOriginal,cmap="gray"),plt.title("Original")
    # plt.subplot(235),plt.imshow(nextLabeled),plt.title("nextLabeled")
    # plt.subplot(236),plt.imshow(nextSegment,cmap="gray"),plt.title("result")
    # plt.show()

    # Export image
    try:
        cv.imwrite(nextSegmentAddress, nextSegment)
    except (cv.error, Exception):
        return "Picture is saved incorrectly"
    return nextSegment