Exemple #1
0
def graphcut_multi(unary1, unary2, pw_x, pw_y, alpha, beta, eta, n_labels=2):
    '''alpha-beta swap algorithm'''
    block_num = unary1.shape[0]
    
    large_val = 1000 * block_num ** 2 
    
    if n_labels == 2:
        prior= eta * np.array([-np.log(alpha + 1e-8), -np.log(1 - alpha + 1e-8)]) / block_num ** 2
    elif n_labels == 3:
        prior= eta * np.array([-np.log(alpha**2 + 1e-8), -np.log(2 * alpha * (1-alpha) + 1e-8), -np.log((1 - alpha)**2 + 1e-8)]) / block_num ** 2
    elif n_labels == 4:
        prior= eta * np.array([-np.log(alpha**3 + 1e-8), -np.log(3 * alpha **2 * (1-alpha) + 1e-8), 
                             -np.log(3 * alpha * (1-alpha) **2 + 1e-8), -np.log((1 - alpha)**3 + 1e-8)]) / block_num ** 2
        
    unary_cost =  (large_val * np.stack([(1-lam) * unary1 + lam * unary2 + prior[i] for i, lam in enumerate(np.linspace(0,1, n_labels))], axis=-1)).astype(np.int32)
    pairwise_cost = np.zeros(shape=[n_labels, n_labels], dtype=np.float32)

    for i in range(n_labels):
        for j in range(n_labels):
            pairwise_cost[i, j] = (i-j)**2 / (n_labels-1)**2

    pw_x = (large_val * (pw_x + beta)).astype(np.int32)
    pw_y = (large_val * (pw_y + beta)).astype(np.int32)

    labels = 1.0 - gco.cut_grid_graph(unary_cost, pairwise_cost, pw_x, pw_y, algorithm='swap')/(n_labels-1)
    mask = labels.reshape(block_num, block_num)

    return mask
Exemple #2
0
def splitlabel(lmap, mask, prev, slbls, ucost0, ewts, opt):
    """Split a new connected component that overlaps multiple components"""

    _ys, _xs = np.where(mask)
    _y1, _y2, _x1, _x2 = np.amin(_ys), np.amax(_ys), np.amin(_xs), np.amax(_xs)

    prev = prev[_y1:(_y2 + 1), _x1:(_x2 + 1)]
    ucost0 = ucost0[_y1:(_y2 + 1), _x1:(_x2 + 1)]
    ucost = np.zeros(np.shape(ucost0) + (len(slbls) + 1, ), np.int32)
    ucost[:, :, 0] = ucost0

    ewts = [
        ewts[0][_y1:_y2, _x1:(_x2 + 1)], ewts[1][_y1:(_y2 + 1), _x1:_x2],
        ewts[2][_y1:_y2, _x1:_x2], ewts[3][_y1:_y2, _x1:_x2]
    ]

    ucost[prev > 0, :] = ucost[prev > 0, :] + opt.zwt
    for i, lbl in enumerate(slbls):
        ucost[prev == lbl, i + 1] = 0

    pwcost = 1 - np.eye(len(slbls) + 1, dtype=np.int32)

    mcut0 = gco.cut_grid_graph(ucost, pwcost, *ewts).reshape(ucost0.shape)
    mcut = np.zeros_like(lmap)
    mcut[_y1:(_y2 + 1), _x1:(_x2 + 1)] = mcut0
    for i, lbl in enumerate(slbls):
        lmap[np.logical_and(mask, mcut == (i + 1))] = lbl
Exemple #3
0
def graphcut_multi(cost, beta=1, algorithm='swap', n_label=0, add_idx=None):
    height, width, n_input = cost.shape

    unary = np.ascontiguousarray(cost)

    if add_idx is not None:
        add_idx = add_idx.astype(np.bool)
    pairwise = (np.ones(shape=(n_input, n_input), dtype=np.float32) -
                np.eye(n_input, dtype=np.float32))
    if n_label == 2:
        pairwise[-1, :-1][add_idx] = 0.25
        pairwise[:-1, -1][add_idx] = 0.25
    elif n_label == 3:
        pairwise[-3:, :-3][:, add_idx] = np.array([[0.25, 0.25, 1],
                                                   [0.25, 1, 0.25],
                                                   [1, 0.25, 0.25]])
        pairwise[:-3, -3:][add_idx, :] = np.array([[0.25, 0.25, 1],
                                                   [0.25, 1, 0.25],
                                                   [1, 0.25, 0.25]])

    cost_v = beta * np.ones(shape=[height - 1, width], dtype=np.float32)
    cost_h = beta * np.ones(shape=[height, width - 1], dtype=np.float32)

    mask_idx = gco.cut_grid_graph(unary,
                                  pairwise,
                                  cost_v,
                                  cost_h,
                                  algorithm='swap')

    return mask_idx
Exemple #4
0
def graphcut_multi_float(unary1,
                         unary2,
                         pw_x,
                         pw_y,
                         alpha,
                         beta,
                         eta,
                         n_labels=2,
                         label_cost='l2',
                         beta_c=0.0):
    block_num = unary1.shape[-1]

    if n_labels == 2:
        prior = eta * np.array(
            [-np.log(alpha + 1e-8), -np.log(1 - alpha + 1e-8)]) / block_num**2
    elif n_labels == 3:
        prior = eta * np.array([
            -np.log(alpha**2 + 1e-8), -np.log(2 * alpha * (1 - alpha) + 1e-8),
            -np.log((1 - alpha)**2 + 1e-8)
        ]) / block_num**2
    elif n_labels == 4:
        prior = eta * np.array([
            -np.log(alpha**3 + 1e-8), -np.log(3 * alpha**2 *
                                              (1 - alpha) + 1e-8),
            -np.log(3 * alpha *
                    (1 - alpha)**2 + 1e-8), -np.log((1 - alpha)**3 + 1e-8)
        ]) / block_num**2

    unary_cost = np.stack(
        [(1 - lam) * unary1 + lam * unary2 + prior[i]
         for i, lam in enumerate(np.linspace(0, 1, n_labels))],
        axis=-1)
    pairwise_cost = np.zeros(shape=[n_labels, n_labels], dtype=np.float32)

    for i in range(n_labels):
        for j in range(n_labels):
            if label_cost == 'l1':
                pairwise_cost[i, j] = abs(i - j) / (n_labels - 1)
            elif label_cost == 'l2':
                pairwise_cost[i, j] = (i - j)**2 / (n_labels - 1)**2
            elif laabel_cost == 'l4':
                pairwise_cost[i, j] = (i - j)**4 / (n_labels - 1)**4
            else:
                raise AssertionError(
                    "label cost should be one of ['l1', 'l2', 'l4']")

    pw_x = pw_x + beta
    pw_y = pw_y + beta

    labels = 1.0 - gco.cut_grid_graph(
        unary_cost, pairwise_cost, pw_x, pw_y,
        algorithm='swap') / (n_labels - 1)
    mask = labels.reshape(block_num, block_num)

    return mask
Exemple #5
0
def label(img, prev, opt=_PLOPT):
    """Label all plants in an image, using previous labels as guide."""

    # Do a binary segmentation first
    ucost = np.zeros([img.shape[0], img.shape[1], 2], np.int32)
    ucost0 = ((unary(img, opt) - 0.5) * opt.uwt).astype(np.int32)
    ucost[:, :, 0] = ucost0
    pwcost = 1 - np.eye(2, dtype=np.int32)
    if prev is not None:
        ucost[prev > 0, 0] = ucost[prev > 0, 0] + opt.zwt

    ewts = pairwise(img, opt)
    ewts = [(f * opt.ewt).astype(np.int32) for f in ewts]

    binary = gco.cut_grid_graph(ucost, pwcost, *ewts).reshape(img.shape[:2])

    # Then label individual plants
    plants = separateconnect(binary, prev, ucost0, ewts, opt)

    return plants
Exemple #6
0
def graphcut_multi(unary1, unary2, pw_x, pw_y, beta, n_labels=2):
    block_num = unary1.shape[0]
    alpha = 1000 * block_num**2
    unary_cost = np.stack([(1 - i) * alpha * unary1 + i * alpha * unary2
                           for i in np.linspace(0, 1, n_labels)],
                          axis=-1).astype(np.int32)

    pairwise_cost = np.zeros(shape=[n_labels, n_labels], dtype=np.float32)
    for i in range(n_labels):
        for j in range(n_labels):
            pairwise_cost[i, j] = (1 - i / 2) * j / 2 + i / 2 * (1 - j / 2)

    pw_x = (alpha * (pw_x + beta)).astype(np.int32)
    pw_y = (alpha * (pw_y + beta)).astype(np.int32)

    labels = 1.0 - gco.cut_grid_graph(
        unary_cost, pairwise_cost, pw_x, pw_y,
        algorithm='swap') / (n_labels - 1)
    mask = labels.reshape(block_num, block_num)

    return mask
Exemple #7
0
def graphcut_multi(cost, beta=1, algorithm='swap', n_label=0, add_idx=None):
    '''find optimal labeling using Graph-Cut algorithm'''
    s = time.time()
    height, width, n_input = cost.shape
    
    unary = np.ascontiguousarray(cost)
    pairwise = (np.ones(shape=(n_input,n_input), dtype=np.float32) - np.eye(n_input, dtype=np.float32))
    if n_label == 2:
        pairwise[-1, :-1][add_idx] = 0.25
        pairwise[:-1, -1][add_idx] = 0.25
    elif n_label == 3:
        pairwise[-3:, :-3][:, add_idx] = np.array([[0.25, 0.25, 1], [0.25, 1, 0.25], [1, 0.25, 0.25]])
        pairwise[:-3, -3:][add_idx, :] = np.array([[0.25, 0.25, 1], [0.25, 1, 0.25], [1, 0.25, 0.25]])
    
    cost_v =  beta * np.ones(shape=[height-1, width], dtype=np.float32)
    cost_h =  beta * np.ones(shape=[height, width-1], dtype=np.float32)   
    #print("forward- mixup- mask_onehot- gc_pre: {:.4f}".format(time.time()-s))

    s = time.time()
    mask_idx = gco.cut_grid_graph(unary, pairwise, cost_v, cost_h, algorithm=algorithm)
    #print("forward- mixup- mask_onehot- gc_solve: {:.4f}".format(time.time()-s))
    return mask_idx
Exemple #8
0
def joincc(lmap, prev, ucost0, ewts, opt):
    """Create joins to ensure each plant is one connected component."""

    pwcost = 1 - np.eye(2, dtype=np.int32)
    for lbl in range(1, np.amax(lmap) + 1):
        ncc = ndi.label(lmap == lbl)[1]
        if ncc <= 1:
            continue

        # Crop out portions just including that component
        _y, _x = np.where(lmap == lbl)
        _y1, _y2 = np.amin(_y), np.amax(_y) + 1
        _x1, _x2 = np.amin(_x), np.amax(_x) + 1

        lmxy = lmap[_y1:_y2, _x1:_x2]
        uc0 = (ucost0[_y1:_y2, _x1:_x2]).copy()
        if prev is not None:
            uc0[prev[_y1:_y2, _x1:_x2] == lbl] = \
                uc0[prev[_y1:_y2, _x1:_x2] == lbl] + opt.zwt

        chull = np.logical_and(chi(lmxy == lbl), lmxy == 0)
        ucost = np.zeros([lmxy.shape[0], lmxy.shape[1], 2], np.int32)
        ucost[:, :, 0] = -opt.uwt
        ucost[lmxy == lbl, 0] = opt.uwt
        ucost[chull, 0] = uc0[chull]

        ew0 = [
            ewts[0][_y1:(_y2 - 1), _x1:_x2], ewts[1][_y1:_y2, _x1:(_x2 - 1)],
            ewts[2][_y1:(_y2 - 1), _x1:(_x2 - 1)], ewts[3][_y1:(_y2 - 1),
                                                           _x1:(_x2 - 1)]
        ]

        joined = False
        for _ in range(opt.joinit):
            # Do a graph cut after biasing the background
            ucost[chull, 0] = ucost[chull, 0] + opt.joininc
            lmxy2 = gco.cut_grid_graph(ucost, pwcost, *ew0).reshape(lmxy.shape)

            if ndi.label(lmxy2 == 1)[1] == 1:
                # Now, see if we can remove some of the added components
                newcomps, nnc = ndi.label(np.logical_and(
                    lmxy2 == 1, lmxy == 0))
                if nnc > 1:
                    scores = np.bincount(newcomps.flatten(), uc0.flatten())
                    cidx = np.argsort(scores[1:]) + 1
                    for ncidx in cidx:
                        lmxy2b = lmxy2.copy()
                        lmxy2b[newcomps == ncidx] = 0
                        if ndi.label(lmxy2b)[1] == 1:
                            lmxy2 = lmxy2b

                # Patch things back in
                lmxy[lmxy2 == 1] = lbl
                lmap[_y1:_y2, _x1:_x2] = lmxy
                joined = True
                break

        if not joined:
            ccxy = ndi.label(lmxy == lbl)[0]
            ccount = np.bincount(ccxy.flatten())
            ccsort = np.argsort(-ccount[1:])
            for idx in range(1, len(ccsort)):
                lmxy[ccxy == (ccsort[idx] + 1)] = 0
            lmap[_y1:_y2, _x1:_x2] = lmxy

    return lmap