Ejemplo n.º 1
0
def tps_rpm_bootstrap(x_nd, y_md, z_kd, xy_corr, n_init_iter = 10, n_iter = 20, reg_init = .1, reg_final = .001, rad_init = .1, rad_final = .005, rot_reg = 1e-3, 
            plotting = False, plot_cb = None, old_xyz=None, new_xyz=None):
    """
    modification for tps_rpm in order to use bootstrapping info

    return a warp taking x to z, proceeds by warping y->z, then intializes tps_rpm with the correspondences from that warping
    """
    _, _, yz_corr = tps_rpm_bij(y_md, z_kd, n_iter = n_iter, reg_init = reg_init, reg_final = reg_final, 
                                rad_init = rad_init, rad_final = rad_final, rot_reg = rot_reg, plotting=plotting,
                                plot_cb = plot_cb, old_xyz = old_xyz, new_xyz = new_xyz, return_corr = True)
    xz_corr = xy_corr.dot(yz_corr)
    # corr_nk, r_N, _ =  balance_matrix3(xz_corr, 10, 1e-1, 1e-2)
    # corr_nk += 1e-9
    corr_nk = xz_corr
        
    wt_n = corr_nk.sum(axis=1)
    wt_k = corr_nk.sum(axis=0)

    xtarg_nd = (corr_nk/wt_n[:,None]).dot(z_kd)
    ztarg_kd = (corr_nk/wt_k[None,:]).T.dot(x_nd)

    f = fit_ThinPlateSpline(x_nd, xtarg_nd, bend_coef = reg_final, wt_n=wt_n, rot_coef = rot_reg)
    g = fit_ThinPlateSpline(z_kd, ztarg_kd, bend_coef = reg_final, wt_n=wt_k, rot_coef = rot_reg)
    f._cost = tps.tps_cost(f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, reg_final, wt_n=wt_n)/wt_n.mean()
    g._cost = tps.tps_cost(g.lin_ag, g.trans_g, g.w_ng, g.x_na, ztarg_kd, reg_final, wt_n=wt_k)/wt_k.mean()
    print 'cost:\t', f._cost + g._cost
    return (f, g, corr_nk)
Ejemplo n.º 2
0
def tps_rpm_bij_presolve(x_nd, y_md, fsolve, gsolve,n_iter = 20, reg_init = .1, 
                         reg_final = .001, rad_init = .1, rad_final = .005, 
                         rot_reg = 1e-3, outlierprior=1e-1, outlierfrac=2e-1, vis_cost_xy=None, return_corr=False, check_solver=False):
    """
    tps-rpm algorithm mostly as described by chui and rangaran
    reg_init/reg_final: regularization on curvature
    rad_init/rad_final: radius for correspondence calculation (meters)
    plotting: 0 means don't plot. integer n means plot every n iterations
    """
    
    _,d=x_nd.shape
    regs = np.around(loglinspace(reg_init, reg_final, n_iter), BEND_COEF_DIGITS)
    rads = loglinspace(rad_init, rad_final, n_iter)

    f = ThinPlateSpline(d)
    f.trans_g = np.median(y_md,axis=0) - np.median(x_nd,axis=0)

    g = ThinPlateSpline(d)
    g.trans_g = -f.trans_g


    # r_N = None
    
    for i in xrange(n_iter):
        xwarped_nd = f.transform_points(x_nd)
        ywarped_md = g.transform_points(y_md)
        
        fwddist_nm = ssd.cdist(xwarped_nd, y_md,'euclidean')
        invdist_nm = ssd.cdist(x_nd, ywarped_md,'euclidean')
        
        r = rads[i]
        prob_nm = np.exp( -(fwddist_nm + invdist_nm) / (2*r) )
        corr_nm, r_N, _ =  balance_matrix3(prob_nm, 10, outlierprior, outlierfrac)
        corr_nm += 1e-9
        
        wt_n = corr_nm.sum(axis=1)
        wt_m = corr_nm.sum(axis=0)

        xtarg_nd = (corr_nm/wt_n[:,None]).dot(y_md)
        ytarg_md = (corr_nm/wt_m[None,:]).T.dot(x_nd)                

        fsolve.solve(wt_n, xtarg_nd, regs[i], rot_reg, f)        
        gsolve.solve(wt_m, ytarg_md, regs[i], rot_reg, g)
        if check_solver:
            f_test = fit_ThinPlateSpline(x_nd, xtarg_nd, bend_coef = regs[i], wt_n=wt_n, rot_coef = rot_reg)
            g_test = fit_ThinPlateSpline(y_md, ytarg_md, bend_coef = regs[i], wt_n=wt_m, rot_coef = rot_reg)
            tol = 1e-4
            assert np.allclose(f.trans_g, f_test.trans_g, atol=tol)
            assert np.allclose(f.lin_ag, f_test.lin_ag, atol=tol)
            assert np.allclose(f.w_ng, f_test.w_ng, atol=tol)
            assert np.allclose(g.trans_g, g_test.trans_g, atol=tol)
            assert np.allclose(g.lin_ag, g_test.lin_ag, atol=tol)
            assert np.allclose(g.w_ng, g_test.w_ng, atol=tol)

    f._cost = tps.tps_cost(f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, regs[i], wt_n=wt_n)/wt_n.mean()
    g._cost = tps.tps_cost(g.lin_ag, g.trans_g, g.w_ng, g.x_na, ytarg_md, regs[i], wt_n=wt_m)/wt_m.mean()
    if return_corr:
        return (f, g), corr_nm
    return f,g
Ejemplo n.º 3
0
def tps_rpm_bij(x_nd, y_md, n_iter = 20, reg_init = .1, reg_final = .001, rad_init = .1, rad_final = .005, 
                rot_reg = 1e-3):
    """
    tps-rpm algorithm mostly as described by chui and rangaran
    reg_init/reg_final: regularization on curvature
    rad_init/rad_final: radius for correspondence calculation (meters)
    plotting: 0 means don't plot. integer n means plot every n iterations
    """
    
    _,d=x_nd.shape
    regs = loglinspace(reg_init, reg_final, n_iter)
    rads = loglinspace(rad_init, rad_final, n_iter)
    if not f_init:
        f = ThinPlateSpline(d)
        f.trans_g = np.median(y_md,axis=0) - np.median(x_nd,axis=0)
    else:
        f = f_init
    if not f_init:
        g = ThinPlateSpline(d)
        g.trans_g = -f.trans_g
    else:
        g = g_init


    # r_N = None
    
    for i in xrange(n_iter):
        xwarped_nd = f.transform_points(x_nd)
        ywarped_md = g.transform_points(y_md)
        
        fwddist_nm = ssd.cdist(xwarped_nd, y_md,'euclidean')
        invdist_nm = ssd.cdist(x_nd, ywarped_md,'euclidean')
        
        r = rads[i]
        prob_nm = np.exp( -(fwddist_nm + invdist_nm) / (2*r) )
        corr_nm, r_N, _ =  balance_matrix3(prob_nm, 10, 1e-1, 1e-2)
        corr_nm += 1e-9
        
        wt_n = corr_nm.sum(axis=1)
        wt_m = corr_nm.sum(axis=0)

        inlier = wt_n > 1e-2
        xtarg_nd = np.empty(x_nd.shape)
        xtarg_nd[inlier, :] = (corr_nm/wt_n[:,None]).dot(y_md)[inlier, :]
        xtarg_nd[~inlier, :] = xwarped_nd[~inlier, :] 

        inlier = wt_m > 1e-2
        ytarg_md = np.empty(y_md.shape)
        ytarg_md[inlier, :] = (corr_nm/wt_m[:,None]).dot(y_md)[inlier, :]
        ytarg_md[~inlier, :] = ywarped_md[~inlier, :] 
                
        f = fit_ThinPlateSpline(x_nd, xtarg_nd, bend_coef = regs[i], wt_n=wt_n, rot_coef = rot_reg)
        g = fit_ThinPlateSpline(y_md, ytarg_md, bend_coef = regs[i], wt_n=wt_m, rot_coef = rot_reg)

    f._cost = tps.tps_cost(f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, regs[i], wt_n=wt_n)/wt_n.mean()
    g._cost = tps.tps_cost(g.lin_ag, g.trans_g, g.w_ng, g.x_na, ytarg_md, regs[i], wt_n=wt_m)/wt_m.mean()
    if return_corr:
        return f, g, corr_nm
    return f,g
Ejemplo n.º 4
0
def fit_ThinPlateSpline_corr(x_nd, y_md, corr_nm, l, rot_reg, x_weights = None):
    wt_n = corr_nm.sum(axis=1)

    if np.any(wt_n == 0):
        inlier = wt_n != 0
        x_nd = x_nd[inlier,:]
        wt_n = wt_n[inlier,:]
        x_weights = x_weights[inlier]
        xtarg_nd = (corr_nm[inlier,:]/wt_n[:,None]).dot(y_md)
    else:
        xtarg_nd = (corr_nm/wt_n[:,None]).dot(y_md)

    if x_weights is not None:
        if x_weights.ndim > 1:
            wt_n=wt_n[:,None]*x_weights
        else:
            wt_n=wt_n*x_weights
    
    f = fit_ThinPlateSpline(x_nd, xtarg_nd, bend_coef = l, wt_n = wt_n, rot_coef = rot_reg)
    f._bend_coef = l
    f._wt_n = wt_n
    f._rot_coef = rot_reg
    f._cost = tps.tps_cost(f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, l, wt_n=wt_n)/wt_n.mean()
    
    return f
Ejemplo n.º 5
0
def rpm_em_step_stat(x_nd, y_md, l, T, rot_reg, prev_f, vis_cost_xy = None, outlierprior = 1e-2, normalize_iter = 20, T0 = .04, user_data=None):
    """
    Statiscal interpretation of the RPM EM step
    """
    n,d = x_nd.shape
    m,_ = y_md.shape
    xwarped_nd = prev_f.transform_points(x_nd)
    
    dist_nm = ssd.cdist(xwarped_nd, y_md, 'sqeuclidean')
    outlier_dist_1m = ssd.cdist(xwarped_nd.mean(axis=0)[None,:], y_md, 'sqeuclidean')
    outlier_dist_n1 = ssd.cdist(xwarped_nd, y_md.mean(axis=0)[None,:], 'sqeuclidean')

    # Note: proportionality constants within a column can be ignored since Sinkorn balancing normalizes the columns first
    prob_nm = np.exp( -(dist_nm / (2*T)) + (outlier_dist_1m / (2*T0)) ) / np.sqrt(T) # divide by np.exp( outlier_dist_1m / (2*T0) ) to prevent prob collapsing to zero
    if vis_cost_xy != None:
        pi = np.exp( -vis_cost_xy )
        pi /= pi.sum(axis=0)[None,:] # normalize along columns; these are proper probabilities over j = 1,...,N
        prob_nm *= (1. - outlierprior) * pi
    else:
        prob_nm *= (1. - outlierprior) / float(n)
    outlier_prob_1m = outlierprior * np.ones((1,m)) / np.sqrt(T0) # divide by np.exp( outlier_dist_1m / (2*T0) )
    outlier_prob_n1 = np.exp( -outlier_dist_n1 / (2*T0) ) / np.sqrt(T0)
    prob_NM = np.empty((n+1, m+1), 'f4')
    prob_NM[:n, :m] = prob_nm
    prob_NM[:n, m][:,None] = outlier_prob_n1
    prob_NM[n, :m][None,:] = outlier_prob_1m
    prob_NM[n, m] = 0
    
    r_N, c_M = sinkhorn_balance_coeffs(prob_NM, normalize_iter)
    prob_NM *= r_N[:,None]
    prob_NM *= c_M[None,:]
    # prob_NM needs to be row-normalized at this point
    corr_nm = prob_NM[:n, :m]
    
    wt_n = corr_nm.sum(axis=1)

    # discard points that are outliers (i.e. their total correspondence is smaller than 1e-2)    
    inlier = wt_n > 1e-2
    if np.any(~inlier):
        x_nd = x_nd[inlier,:]
        wt_n = wt_n[inlier,:]
        xtarg_nd = (corr_nm[inlier,:]/wt_n[:,None]).dot(y_md)
    else:
        xtarg_nd = (corr_nm/wt_n[:,None]).dot(y_md)

    f = fit_ThinPlateSpline(x_nd, xtarg_nd, bend_coef = l, wt_n = wt_n, rot_coef = rot_reg)
    f._bend_coef = l
    f._rot_coef = rot_reg
    f._cost = tps.tps_cost(f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, l, wt_n=wt_n)/wt_n.mean()

    return f, corr_nm
Ejemplo n.º 6
0
def tps_rpm(x_nd, y_md, n_iter = 5, reg_init = .1, reg_final = .001, rad_init = .2, rad_final = .001, plotting = False, verbose=True, f_init = None, return_full = False, plot_cb = None):
    """
    tps-rpm algorithm mostly as described by chui and rangaran
    reg_init/reg_final: regularization on curvature
    rad_init/rad_final: radius for correspondence calculation (meters)
    plotting: 0 means don't plot. integer n means plot every n iterations
    """
    n,d = x_nd.shape
    regs = loglinspace(reg_init, reg_final, n_iter)
    rads = loglinspace(rad_init, rad_final, n_iter)
    if f_init is not None: 
        f = f_init  
    else:
        f = ThinPlateSpline(d)
        f.trans_g = np.median(y_md,axis=0) - np.median(x_nd,axis=0)
    if plot_cb is None:
        plot_cb = default_plot_callback
    for i in xrange(n_iter):
        xwarped_nd = f.transform_points(x_nd)
        # targ_nd = find_targets(x_nd, y_md, corr_opts = dict(r = rads[i], p = .1))
        corr_nm = calc_correspondence_matrix(xwarped_nd, y_md, r=rads[i], p=.2)

        wt_n = corr_nm.sum(axis=1)

        goodn = wt_n > .1

        targ_Nd = np.dot(corr_nm[goodn, :]/wt_n[goodn][:,None], y_md)
        
        if plotting and i%plotting==0:
            plot_cb(x_nd, y_md, targ_Nd, corr_nm, wt_n, f)
        
        
        x_Nd = x_nd[goodn]
        f.fit(x_Nd, targ_Nd, bend_coef = regs[i], wt_n = wt_n[goodn], rot_coef = 10*regs[i], verbose=verbose)


    if return_full:
        info = {}
        info["corr_nm"] = corr_nm
        info["goodn"] = goodn
        info["x_Nd"] = x_nd[goodn,:]
        info["targ_Nd"] = targ_Nd
        info["wt_N"] = wt_n[goodn]
        info["cost"] = tps.tps_cost(f.lin_ag, f.trans_g, f.w_ng, x_Nd, targ_Nd, regs[-1])
        return f, info
    else:
        return f
Ejemplo n.º 7
0
def tps_rpm_bij(x_nd,
                y_md,
                n_iter=20,
                reg_init=.1,
                reg_final=.001,
                rad_init=.1,
                rad_final=.005,
                rot_reg=1e-3,
                plotting=False,
                plot_cb=None,
                x_weights=None,
                y_weights=None,
                outlierprior=.1,
                outlierfrac=2e-1,
                vis_cost_xy=None,
                return_corr=False):
    """
    tps-rpm algorithm mostly as described by chui and rangaran
    reg_init/reg_final: regularization on curvature
    rad_init/rad_final: radius for correspondence calculation (meters)
    plotting: 0 means don't plot. integer n means plot every n iterations
    interest_pts are points in either scene where we want a lower prior of outliers
    x_weights: rescales the weights of the forward tps fitting of the last iteration
    y_weights: same as x_weights, but for the backward tps fitting
    """
    _, d = x_nd.shape
    regs = loglinspace(reg_init, reg_final, n_iter)
    rads = loglinspace(rad_init, rad_final, n_iter)

    f = ThinPlateSpline(d)
    scale = (np.max(y_md, axis=0) - np.min(y_md, axis=0)) / (
        np.max(x_nd, axis=0) - np.min(x_nd, axis=0))
    f.lin_ag = np.diag(scale)  # align the mins and max
    f.trans_g = np.median(
        y_md, axis=0) - np.median(x_nd, axis=0) * scale  # align the medians
    # do a coarse search through rotations
    # fit_rotation(f, x_nd, y_md)

    g = ThinPlateSpline(d)
    g.lin_ag = np.diag(1. / scale)
    g.trans_g = -np.diag(1. / scale).dot(f.trans_g)

    # set up outlier priors for source and target scenes
    n, _ = x_nd.shape
    m, _ = y_md.shape

    x_priors = np.ones(n) * outlierprior
    y_priors = np.ones(m) * outlierprior

    # r_N = None

    for i in xrange(n_iter):
        xwarped_nd = f.transform_points(x_nd)
        ywarped_md = g.transform_points(y_md)

        fwddist_nm = ssd.cdist(xwarped_nd, y_md, 'euclidean')
        invdist_nm = ssd.cdist(x_nd, ywarped_md, 'euclidean')

        r = rads[i]
        prob_nm = np.exp(-(fwddist_nm + invdist_nm) / (2 * r))
        if vis_cost_xy != None:
            pi = np.exp(-vis_cost_xy)
            pi /= pi.max(
            )  # rescale the maximum probability to be 1. effectively, the outlier priors are multiplied by a
            # visual prior of 1 (since the outlier points have a visual prior of 1 with any point)
            prob_nm *= pi

        corr_nm, r_N, _ = balance_matrix3(
            prob_nm, 10, x_priors, y_priors,
            outlierfrac)  # edit final value to change outlier percentage
        corr_nm += 1e-9

        wt_n = corr_nm.sum(axis=1)
        wt_m = corr_nm.sum(axis=0)

        xtarg_nd = (corr_nm / wt_n[:, None]).dot(y_md)
        ytarg_md = (corr_nm / wt_m[None, :]).T.dot(x_nd)

        if plotting and i % plotting == 0:
            plot_cb(x_nd, y_md, xtarg_nd, corr_nm, wt_n, f)

        if i == (n_iter - 1):
            if x_weights is not None:
                wt_n = wt_n * x_weights
            if y_weights is not None:
                wt_m = wt_m * y_weights
        f = fit_ThinPlateSpline(x_nd,
                                xtarg_nd,
                                bend_coef=regs[i],
                                wt_n=wt_n,
                                rot_coef=rot_reg)
        g = fit_ThinPlateSpline(y_md,
                                ytarg_md,
                                bend_coef=regs[i],
                                wt_n=wt_m,
                                rot_coef=rot_reg)

    f._cost = tps_cost(
        f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, regs[i],
        wt_n=wt_n) / wt_n.mean()
    g._cost = tps_cost(
        g.lin_ag, g.trans_g, g.w_ng, g.x_na, ytarg_md, regs[i],
        wt_n=wt_m) / wt_m.mean()
    if return_corr:
        return (f, g), corr_nm
    return f, g
Ejemplo n.º 8
0
def tps_rpm_bij(x_nd, y_md, n_iter=20, reg_init=.1, reg_final=.001, rad_init=.1, rad_final=.005,
             rot_reg = 1e-3, plotting = False, plot_cb = None, x_weights = None, y_weights = None, 
             outlierprior = .1, outlierfrac = 2e-1, vis_cost_xy = None, return_corr=False):
    """
    tps-rpm algorithm mostly as described by chui and rangaran
    reg_init/reg_final: regularization on curvature
    rad_init/rad_final: radius for correspondence calculation (meters)
    plotting: 0 means don't plot. integer n means plot every n iterations
    interest_pts are points in either scene where we want a lower prior of outliers
    x_weights: rescales the weights of the forward tps fitting of the last iteration
    y_weights: same as x_weights, but for the backward tps fitting
    """
    _,d=x_nd.shape
    regs = loglinspace(reg_init, reg_final, n_iter)
    rads = loglinspace(rad_init, rad_final, n_iter)

    f = ThinPlateSpline(d)
    scale = (np.max(y_md,axis=0) - np.min(y_md,axis=0)) / (np.max(x_nd,axis=0) - np.min(x_nd,axis=0))
    f.lin_ag = np.diag(scale) # align the mins and max
    f.trans_g = np.median(y_md,axis=0) - np.median(x_nd,axis=0) * scale  # align the medians
    # do a coarse search through rotations
    # fit_rotation(f, x_nd, y_md)
    
    g = ThinPlateSpline(d)
    g.lin_ag = np.diag(1./scale)
    g.trans_g = -np.diag(1./scale).dot(f.trans_g)

    # set up outlier priors for source and target scenes
    n, _ = x_nd.shape
    m, _ = y_md.shape

    x_priors = np.ones(n)*outlierprior    
    y_priors = np.ones(m)*outlierprior    

    # r_N = None
    
    for i in xrange(n_iter):
        xwarped_nd = f.transform_points(x_nd)
        ywarped_md = g.transform_points(y_md)
        
        fwddist_nm = ssd.cdist(xwarped_nd, y_md,'euclidean')
        invdist_nm = ssd.cdist(x_nd, ywarped_md,'euclidean')
        
        r = rads[i]
        prob_nm = np.exp( -(fwddist_nm + invdist_nm) / (2*r) )
        if vis_cost_xy != None:
            pi = np.exp( -vis_cost_xy )
            pi /= pi.max() # rescale the maximum probability to be 1. effectively, the outlier priors are multiplied by a 
                           # visual prior of 1 (since the outlier points have a visual prior of 1 with any point)
            prob_nm *= pi

        corr_nm, r_N, _ =  balance_matrix3(prob_nm, 10, x_priors, y_priors, outlierfrac) # edit final value to change outlier percentage
        corr_nm += 1e-9
        
        wt_n = corr_nm.sum(axis=1)
        wt_m = corr_nm.sum(axis=0)

        xtarg_nd = (corr_nm/wt_n[:,None]).dot(y_md)
        ytarg_md = (corr_nm/wt_m[None,:]).T.dot(x_nd)
        
        if plotting and i%plotting==0:
            plot_cb(x_nd, y_md, xtarg_nd, corr_nm, wt_n, f)
        
        if i == (n_iter-1):
            if x_weights is not None:
                wt_n=wt_n*x_weights
            if y_weights is not None:
                wt_m=wt_m*y_weights
        f = fit_ThinPlateSpline(x_nd, xtarg_nd, bend_coef = regs[i], wt_n=wt_n, rot_coef = rot_reg)
        g = fit_ThinPlateSpline(y_md, ytarg_md, bend_coef = regs[i], wt_n=wt_m, rot_coef = rot_reg)
    
    f._cost = tps_cost(f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, regs[i], wt_n=wt_n)/wt_n.mean()
    g._cost = tps_cost(g.lin_ag, g.trans_g, g.w_ng, g.x_na, ytarg_md, regs[i], wt_n=wt_m)/wt_m.mean()
    if return_corr:
        return (f, g), corr_nm
    return f,g
Ejemplo n.º 9
0
def tps_rpm(x_nd,
            y_md,
            n_iter=5,
            reg_init=.1,
            reg_final=.001,
            rad_init=.2,
            rad_final=.001,
            plotting=False,
            verbose=True,
            f_init=None,
            return_full=False,
            plot_cb=None):
    """
    tps-rpm algorithm mostly as described by chui and rangaran
    reg_init/reg_final: regularization on curvature
    rad_init/rad_final: radius for correspondence calculation (meters)
    plotting: 0 means don't plot. integer n means plot every n iterations
    """
    n, d = x_nd.shape
    regs = loglinspace(reg_init, reg_final, n_iter)
    rads = loglinspace(rad_init, rad_final, n_iter)
    if f_init is not None:
        f = f_init
    else:
        f = ThinPlateSpline(d)
        f.trans_g = np.median(y_md, axis=0) - np.median(x_nd, axis=0)
    if plot_cb is None:
        plot_cb = default_plot_callback
    for i in xrange(n_iter):
        xwarped_nd = f.transform_points(x_nd)
        # targ_nd = find_targets(x_nd, y_md, corr_opts = dict(r = rads[i], p = .1))
        corr_nm = calc_correspondence_matrix(xwarped_nd, y_md, r=rads[i], p=.2)

        wt_n = corr_nm.sum(axis=1)

        goodn = wt_n > .1

        targ_Nd = np.dot(corr_nm[goodn, :] / wt_n[goodn][:, None], y_md)

        if plotting and i % plotting == 0:
            plot_cb(x_nd, y_md, targ_Nd, corr_nm, wt_n, f)

        x_Nd = x_nd[goodn]
        f.fit(x_Nd,
              targ_Nd,
              bend_coef=regs[i],
              wt_n=wt_n[goodn],
              rot_coef=10 * regs[i],
              verbose=verbose)

    if return_full:
        info = {}
        info["corr_nm"] = corr_nm
        info["goodn"] = goodn
        info["x_Nd"] = x_nd[goodn, :]
        info["targ_Nd"] = targ_Nd
        info["wt_N"] = wt_n[goodn]
        info["cost"] = tps.tps_cost(f.lin_ag, f.trans_g, f.w_ng, x_Nd, targ_Nd,
                                    regs[-1])
        return f, info
    else:
        return f
Ejemplo n.º 10
0
def tps_rpm_bij(x_nd,
                y_md,
                fsolve,
                gsolve,
                n_iter=20,
                reg_init=.1,
                reg_final=.001,
                rad_init=.1,
                rad_final=.005,
                rot_reg=1e-3,
                outlierprior=1e-1,
                outlierfrac=2e-1,
                vis_cost_xy=None,
                return_corr=False,
                check_solver=False):
    """
    tps-rpm algorithm mostly as described by chui and rangaran
    reg_init/reg_final: regularization on curvature
    rad_init/rad_final: radius for correspondence calculation (meters)
    plotting: 0 means don't plot. integer n means plot every n iterations
    """

    _, d = x_nd.shape
    regs = np.around(loglinspace(reg_init, reg_final, n_iter),
                     BEND_COEF_DIGITS)
    rads = loglinspace(rad_init, rad_final, n_iter)

    f = ThinPlateSpline(d)
    scale = (np.max(y_md, axis=0) - np.min(y_md, axis=0)) / (
        np.max(x_nd, axis=0) - np.min(x_nd, axis=0))
    f.lin_ag = np.diag(scale)  # align the mins and max
    f.trans_g = np.median(
        y_md, axis=0) - np.median(x_nd, axis=0) * scale  # align the medians

    g = ThinPlateSpline(d)
    g.lin_ag = np.diag(1. / scale)
    g.trans_g = -np.diag(1. / scale).dot(f.trans_g)

    # r_N = None

    for i in xrange(n_iter):
        xwarped_nd = f.transform_points(x_nd)
        ywarped_md = g.transform_points(y_md)

        fwddist_nm = ssd.cdist(xwarped_nd, y_md, 'euclidean')
        invdist_nm = ssd.cdist(x_nd, ywarped_md, 'euclidean')

        r = rads[i]
        prob_nm = np.exp(-(fwddist_nm + invdist_nm) / (2 * r))
        corr_nm, r_N, _ = balance_matrix(prob_nm, 10, outlierprior,
                                         outlierfrac)
        corr_nm += 1e-9

        wt_n = corr_nm.sum(axis=1)
        wt_m = corr_nm.sum(axis=0)

        xtarg_nd = (corr_nm / wt_n[:, None]).dot(y_md)
        ytarg_md = (corr_nm / wt_m[None, :]).T.dot(x_nd)

        fsolve.solve(wt_n, xtarg_nd, regs[i], rot_reg, f)
        gsolve.solve(wt_m, ytarg_md, regs[i], rot_reg, g)
        if check_solver:
            f_test = fit_ThinPlateSpline(x_nd,
                                         xtarg_nd,
                                         bend_coef=regs[i],
                                         wt_n=wt_n,
                                         rot_coef=rot_reg)
            g_test = fit_ThinPlateSpline(y_md,
                                         ytarg_md,
                                         bend_coef=regs[i],
                                         wt_n=wt_m,
                                         rot_coef=rot_reg)
            tol = 1e-4
            assert np.allclose(f.trans_g, f_test.trans_g, atol=tol)
            assert np.allclose(f.lin_ag, f_test.lin_ag, atol=tol)
            assert np.allclose(f.w_ng, f_test.w_ng, atol=tol)
            assert np.allclose(g.trans_g, g_test.trans_g, atol=tol)
            assert np.allclose(g.lin_ag, g_test.lin_ag, atol=tol)
            assert np.allclose(g.w_ng, g_test.w_ng, atol=tol)

    f._cost = tps.tps_cost(
        f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, regs[i],
        wt_n=wt_n) / wt_n.mean()
    g._cost = tps.tps_cost(
        g.lin_ag, g.trans_g, g.w_ng, g.x_na, ytarg_md, regs[i],
        wt_n=wt_m) / wt_m.mean()
    if return_corr:
        return (f, g), corr_nm
    return f, g
Ejemplo n.º 11
0
def test_batch_tps_rpm_bij(src_ctx, tgt_ctx, T_init = 1e-1, T_final = 5e-3, 
                           outlierfrac = 1e-2, outlierprior = 1e-1, outliercutoff = .5, em_iter = EM_ITER_CHEAP,
                           test_ind = 0):
    from transformations import ThinPlateSpline, set_ThinPlateSpline
    import tps
    n_iter = len(src_ctx.bend_coefs)
    T_vals = loglinspace(T_init, T_final, n_iter)

    x_nd = src_ctx.pts[test_ind].get()[:src_ctx.dims[test_ind]]
    y_md = tgt_ctx.pts[0].get()[:tgt_ctx.dims[0]]
    (n, d) = x_nd.shape
    (m, _) = y_md.shape

    f = ThinPlateSpline(d)    
    g = ThinPlateSpline(d)    

    src_ctx.reset_tps_params()
    tgt_ctx.reset_tps_params()
    for i, b in enumerate(src_ctx.bend_coefs):
        T = T_vals[i]
        for _ in range(em_iter):
            src_ctx.transform_points()
            tgt_ctx.transform_points()

            xwarped_nd = f.transform_points(x_nd)
            ywarped_md = g.transform_points(y_md)
            gpu_xw = src_ctx.pts_w[test_ind].get()[:n, :]
            gpu_yw = tgt_ctx.pts_w[test_ind].get()[:m, :]
            assert np.allclose(xwarped_nd, gpu_xw, atol=1e-5)
            assert np.allclose(ywarped_md, gpu_yw, atol=1e-5)

            xwarped_nd = gpu_xw
            ywarped_md = gpu_yw

            src_ctx.get_target_points(tgt_ctx, outlierprior, outlierfrac, outliercutoff, T)
            
            fwddist_nm = ssd.cdist(xwarped_nd, y_md,'euclidean')
            invdist_nm = ssd.cdist(x_nd, ywarped_md,'euclidean')
            prob_nm = outlierprior * np.ones((n+1, m+1), np.float32)
            prob_nm[:n, :m] = np.exp( -(fwddist_nm + invdist_nm) / float(2*T))
            prob_nm[n, m] = outlierfrac * np.sqrt(n * m)

            gpu_corr = src_ctx.corr_rm[test_ind].get()
            gpu_corr = gpu_corr.flatten()
            gpu_corr = gpu_corr[:(n + 1) * (m + 1)].reshape(n+1, m+1).astype(np.float32)

            assert np.allclose(prob_nm[:n, :m], gpu_corr[:n, :m], atol=1e-5)
            prob_nm[:n, :m] = gpu_corr[:n, :m]

            r_coefs = np.ones(n+1, np.float32)
            c_coefs = np.ones(m+1, np.float32)
            a_N = np.ones((n+1),dtype = np.float32)
            a_N[n] = m*outlierfrac
            b_M = np.ones((m+1), dtype = np.float32)
            b_M[m] = n*outlierfrac
            for _ in range(DEFAULT_NORM_ITERS):
                r_coefs = a_N/prob_nm.dot(c_coefs)
                rn_c_coefs = c_coefs
                c_coefs = b_M/r_coefs.dot(prob_nm)
            gpu_r_coefs = src_ctx.r_coefs[test_ind].get()[:n+1].reshape(n+1)
            gpu_c_coefs_cn = src_ctx.c_coefs_cn[test_ind].get()[:m+1].reshape(m+1)
            gpu_c_coefs_rn = src_ctx.c_coefs_rn[test_ind].get()[:m+1].reshape(m+1)
            assert np.allclose(r_coefs, gpu_r_coefs, atol=1e-5)
            assert np.allclose(c_coefs, gpu_c_coefs_cn, atol=1e-5)
            assert np.allclose(rn_c_coefs, gpu_c_coefs_rn, atol=1e-5)
            
            prob_nm = prob_nm[:n, :m]
            prob_nm *= gpu_r_coefs[:n, None]
            rn_p_nm = prob_nm * gpu_c_coefs_rn[None, :m]
            cn_p_nm = prob_nm * gpu_c_coefs_cn[None, :m]

            wt_n = rn_p_nm.sum(axis=1)
            gpu_corr_cm = src_ctx.corr_cm[test_ind].get().flatten()[:(n+1)*(m+1)]
            gpu_corr_cm = gpu_corr_cm.reshape(m+1, n+1)## b/c it is column major
            assert np.allclose(wt_n, gpu_corr_cm[m, :n], atol=1e-4)

            
            inlier = wt_n > outliercutoff
            xtarg_nd = np.empty((n, DATA_DIM), np.float32)
            xtarg_nd[inlier, :] = rn_p_nm.dot(y_md)[inlier, :]
            xtarg_nd[~inlier, :] = xwarped_nd[~inlier, :]

            wt_m = cn_p_nm.sum(axis=0)
            assert np.allclose(wt_m, gpu_corr[n, :m], atol=1e-4)

            inlier = wt_m > outliercutoff
            ytarg_md = np.empty((m, DATA_DIM), np.float32)
            ytarg_md[inlier, :] = cn_p_nm.T.dot(x_nd)[inlier, :]
            ytarg_md[~inlier, :] = ywarped_md[~inlier, :]
            
            xt_gpu = src_ctx.pts_t[test_ind].get()[:n, :]
            yt_gpu = tgt_ctx.pts_t[test_ind].get()[:m, :]
            assert np.allclose(xtarg_nd, xt_gpu, atol=1e-4)
            assert np.allclose(ytarg_md, yt_gpu, atol=1e-4)

            src_ctx.update_transform(b)
            tgt_ctx.update_transform(b)

            f_p_mat = src_ctx.proj_mats[b][test_ind].get()[:n+d+1, :n]
            f_o_mat = src_ctx.offset_mats[b][test_ind].get()[:n+d+1]
            b_p_mat = tgt_ctx.proj_mats[b][0].get()[:m+d+1, :m]
            b_o_mat = tgt_ctx.offset_mats[b][0].get()[:m+d+1]
            f_params = f_p_mat.dot(xtarg_nd) + f_o_mat
            g_params = b_p_mat.dot(ytarg_md) + b_o_mat


            gpu_fparams = src_ctx.tps_params[test_ind].get()[:n+d+1]
            gpu_gparams = tgt_ctx.tps_params[test_ind].get()[:m+d+1]
            assert np.allclose(f_params, gpu_fparams, atol=1e-4)
            assert np.allclose(g_params, gpu_gparams, atol=1e-4)


            set_ThinPlateSpline(f, x_nd, gpu_fparams)
            set_ThinPlateSpline(g, y_md, gpu_gparams)

    f._cost = tps.tps_cost(f.lin_ag, f.trans_g, f.w_ng, f.x_na, xtarg_nd, 1)
    g._cost = tps.tps_cost(g.lin_ag, g.trans_g, g.w_ng, g.x_na, ytarg_md, 1)

    gpu_cost = src_ctx.bidir_tps_cost(tgt_ctx)    
    cpu_cost = f._cost + g._cost
    assert np.isclose(gpu_cost[test_ind], cpu_cost, atol=1e-4)