lfd.registration package¶
Class inheritance diagram¶
Submodules¶
lfd.registration.plotting_openrave module¶
lfd.registration.registration module¶
-
class
lfd.registration.registration.BatchGpuTpsRpmBijRegistrationFactory(demos, actionfile=None, n_iter=20, em_iter=1, reg_init=0.1, reg_final=0.0001, rad_init=0.01, rad_final=0.0001, rot_reg=<Mock id='139893060503440'>, outlierprior=0.1, outlierfrac=0.01, prior_fn=None, f_solver_factory=<lfd.registration.solver.GpuTpsSolverFactory object>, g_solver_factory=<lfd.registration.solver.GpuTpsSolverFactory object>)[source]¶ Bases:
lfd.registration.registration.TpsRpmBijRegistrationFactorySimilar to TpsRpmBijRegistrationFactory but batch_register and batch_cost are computed in batch using the GPU
-
class
lfd.registration.registration.BatchGpuTpsRpmRegistrationFactory(demos)[source]¶ Bases:
lfd.registration.registration.TpsRpmRegistrationFactorySimilar to TpsRpmRegistrationFactory but batch_register and batch_cost are computed in batch using the GPU
-
class
lfd.registration.registration.Registration(demo, test_scene_state, f, corr)[source]¶ Bases:
object
-
class
lfd.registration.registration.RegistrationFactory(demos=None)[source]¶ Bases:
object-
batch_cost(test_scene_state)[source]¶ Gets costs of every demonstration scene in demos registered onto the test scene
Returns: A dict that maps from the demonstration names that are in demos to the numpy.array of partial cost
-
batch_register(test_scene_state, callback=None, args=())[source]¶ Registers every demonstration scene in demos onto the test scene
Returns: A dict that maps from the demonstration names that are in demos to the Registration Note
Derived classes might ignore the argument callback
-
cost(demo, test_scene_state)[source]¶ Gets costs of registering the demonstration scene onto the test scene
Parameters: - demo – Demonstration which has the demonstration scene
- test_scene_state – SceneState of the test scene
Returns: A 1-dimensional numpy.array containing the partial costs used for the registration; the sum of these is the objective used for the registration. The exact definition of these partial costs is given by the derived classes.
-
register(demo, test_scene_state, callback=None, args=())[source]¶ Registers demonstration scene onto the test scene
Parameters: - demo – Demonstration which has the demonstration scene
- test_scene_state – SceneState of the test scene
- callback – callback function; the derived classes define the arguments of the functoin
Returns: A Registration
-
-
class
lfd.registration.registration.TpsL2RegistrationFactory(demos=None, n_iter=4, opt_iter=100, reg_init=0.1, reg_final=0.01, rad_init=0.1, rad_final=0.01, rot_reg=<Mock id='139893060503568'>)[source]¶ Bases:
lfd.registration.registration.RegistrationFactoryAs in:
Bing Jian; Vemuri, B.C., “Robust Point Set Registration Using Gaussian Mixture Models,” Pattern Analysis and Machine Intelligence, IEEE Transactions on , vol.33, no.8, pp.1633,1645, Aug. 2011.
Tries to solve the optimization problem

where
computes the L2 distance between two Gaussian mixture models.
-
class
lfd.registration.registration.TpsRpmBijRegistration(demo, test_scene_state, f, g, corr, rad)[source]¶
-
class
lfd.registration.registration.TpsRpmBijRegistrationFactory(demos=None, n_iter=20, em_iter=1, reg_init=0.1, reg_final=0.0001, rad_init=0.01, rad_final=0.0001, rot_reg=<Mock id='139893060503440'>, outlierprior=0.1, outlierfrac=0.01, prior_fn=None, f_solver_factory=<lfd.registration.solver.GpuTpsSolverFactory object>, g_solver_factory=<lfd.registration.solver.GpuTpsSolverFactory object>)[source]¶ Bases:
lfd.registration.registration.RegistrationFactoryAs in:
- Schulman, J. Ho, C. Lee, and P. Abbeel, “Learning from Demonstrations through the Use of Non-Rigid Registration,” in Proceedings of the 16th International Symposium on Robotics Research (ISRR), 2013.
Tries to solve the optimization problem

-
cost(demo, test_scene_state)[source]¶ Gets the costs of the forward and backward thin plate spline objective of the resulting registration
Parameters: - demo – Demonstration which has the demonstration scene
- test_scene_state – SceneState of the test scene
Returns: A 1-dimensional numpy.array containing the residual, bending and rotation cost of the forward and backward spline, each already premultiplied by the respective coefficients.
-
class
lfd.registration.registration.TpsRpmRegistration(demo, test_scene_state, f, corr, rad)[source]¶
-
class
lfd.registration.registration.TpsRpmRegistrationFactory(demos=None, n_iter=20, em_iter=1, reg_init=0.1, reg_final=0.0001, rad_init=0.01, rad_final=0.0001, rot_reg=<Mock id='139893060503440'>, outlierprior=0.1, outlierfrac=0.01, prior_fn=None, f_solver_factory=<lfd.registration.solver.GpuTpsSolverFactory object>)[source]¶ Bases:
lfd.registration.registration.RegistrationFactoryAs in:
- Chui and A. Rangarajan, “A new point matching algorithm for non-rigid registration,” Computer Vision and Image Understanding, vol. 89, no. 2, pp. 114-141, 2003.
Tries to solve the optimization problem

-
cost(demo, test_scene_state)[source]¶ Gets the costs of the thin plate spline objective of the resulting registration
Parameters: - demo – Demonstration which has the demonstration scene
- test_scene_state – SceneState of the test scene
Returns: A 1-dimensional numpy.array containing the residual, bending and rotation cost, each already premultiplied by the respective coefficients.
-
class
lfd.registration.registration.TpsnRpmRegistration(demo, test_scene_state, f, corr_lm, corr_rs, rad, radn, bend_coef, rot_coef)[source]¶
-
class
lfd.registration.registration.TpsnRpmRegistrationFactory(demos=None, n_iter=20, em_iter=1, reg_init=0.1, reg_final=0.0001, rad_init=0.01, rad_final=0.0001, radn_init=0.005, radn_final=0.001, nu_init=0.1, nu_final=10, rot_reg=<Mock id='139893060503440'>, outlierprior=0.1, outlierfrac=0.01, callback=None)[source]¶ Bases:
lfd.registration.registration.RegistrationFactoryTPS-RPM using normals information
lfd.registration.settings module¶
-
lfd.registration.settings.BEND_COEF_DIGITS= 6¶
-
lfd.registration.settings.COV_COEF= 0.1¶
-
lfd.registration.settings.EM_ITER= 1¶ number of inner iterations for RPM algorithms
-
lfd.registration.settings.L2_N_ITER= 4¶
-
lfd.registration.settings.L2_OPT_ITER= 100¶
-
lfd.registration.settings.L2_RAD= (0.1, 0.01)¶
-
lfd.registration.settings.L2_REG= (0.1, 0.01)¶
-
lfd.registration.settings.L2_ROT_REG¶
-
lfd.registration.settings.MAX_CLD_SIZE= 150¶
-
lfd.registration.settings.NU= (0.1, 10)¶ initial and final normals coefficient in TPSN-RPM
-
lfd.registration.settings.N_ITER= 20¶ number of outer iterations for RPM algorithms
-
lfd.registration.settings.OUTLIER_CUTOFF= 0.01¶
-
lfd.registration.settings.OUTLIER_FRAC= 0.01¶
-
lfd.registration.settings.OUTLIER_PRIOR= 0.1¶
-
lfd.registration.settings.RAD= (0.01, 0.0001)¶ initial and final temperature for RPM algorithms
-
lfd.registration.settings.RADN= (0.005, 0.001)¶ initial and final temperature for the normals in TPSN-RPM
-
lfd.registration.settings.REG= (0.1, 0.0001)¶ initial and final smoothing regularizer coefficient for RPM algorithms
-
lfd.registration.settings.ROT_REG¶ rotation regularizer coefficients
lfd.registration.solver module¶
-
class
lfd.registration.solver.TpsSolver(N, QN, NKN, NRN, NR, x_nd, K_nn, rot_coef)[source]¶ Bases:
objectFits thin plate spline to data using precomputed matrix products
lfd.registration.tps module¶
Functions for fitting and applying thin plate spline transformations
-
class
lfd.registration.tps.ThinPlateSpline(d=3)[source]¶ Bases:
lfd.registration.transformation.Transformation-
x_na¶ centers of basis functions
-
w_ng¶ weights of basis functions
-
lin_ag¶ transpose of linear part, so you take x_na.dot(lin_ag)
-
trans_g¶ translation part
-
static
create_from_optimization(x_na, y_ng, bend_coef, rot_coef, wt_n)[source]¶ Solves the optimization problem

Parameters: - x_na – source cloud,

- y_ng – target cloud,

- bend_coef – smoothing, penalize non-affine part,

- rot_coef – angular_spring, penalize rotation,

- wt_n – weight the points,

Returns: A ThinPlateSpline f
- x_na – source cloud,
-
-
lfd.registration.tps.balance_matrix3_cpu(prob_nm, max_iter, row_priors, col_priors, outlierfrac, r_N=None)[source]¶
-
lfd.registration.tps.balance_matrix3_gpu(prob_nm, max_iter, row_priors, col_priors, outlierfrac, r_N=None)[source]¶
-
lfd.registration.tps.balance_matrix4(prob_nm, max_iter, p_n, p_m)[source]¶ Like balance_matrix3 but doesn’t normalize the p_m row and the p_n column
Example
>>> from lfd.registration.tps import balance_matrix4 >>> import numpy as np >>> n, m = (100, 150) >>> prob_nm = np.random.random((n,m)) >>> p_n = 0.1 * np.random.random(n) >>> p_m = 0.1 * np.random.random(m) >>> prob_nm0 = balance_matrix4(prob_nm, 10, p_n, p_m) >>> prob_nm1 = prob_nm.copy() >>> for _ in xrange(10): ... prob_nm1 = prob_nm1 / (prob_nm1.sum(axis=0) + p_m)[None, :] ... prob_nm1 = prob_nm1 / (prob_nm1.sum(axis=1) + p_n)[:, None] ... >>> np.allclose(prob_nm0, prob_nm1) True
-
lfd.registration.tps.l2_distance(x_nd, y_md, rad)[source]¶ Compute the L2 distance between the two Gaussian mixture densities constructed from a moving ‘model’ point set and a fixed ‘scene’ point set at a given ‘scale’. The term that only involves the fixed ‘scene’ is excluded from the returned distance. The gradient with respect to the ‘model’ is calculated and returned as well.
-
lfd.registration.tps.l2_tps(x_ld, y_md, ctrl_nd=None, n_iter=20, opt_iter=400, reg_init=0.1, reg_final=0.0001, rad_init=0.01, rad_final=0.0001, rot_reg=<Mock id='139893060503440'>)[source]¶
-
lfd.registration.tps.loglinspace(start, stop, num)[source]¶ Return numbers spaced with a constant ratio.
Returns num numbers in the interval [start, stop], with constant ratio between consecutive numbers.
Parameters: - start – The starting value of the sequence.
- stop – The end value of the sequence.
- num – Number of samples to generate.
Note
Unlike np.linspace, a singleton sequence with stop is returned when num is 1.
Example
>>> loglinspace(1.0, 100.0, 3) array([ 1., 10., 100.]) >>> loglinspace(10.0, 0.001, 5) array([ 1.00000000e+01, 1.00000000e+00, 1.00000000e-01, 1.00000000e-02, 1.00000000e-03]) >>> loglinspace(2, 4, 1) array([ 4.])
-
lfd.registration.tps.prepare_fit_ThinPlateSpline(x_nd, y_md, corr_nm, fwd=True)[source]¶ Takes into account outlier source points and normalization of points
-
lfd.registration.tps.solve_eqp1(H, f, A, N=None, ret_factorization=False)[source]¶ solve equality-constrained qp min .5 tr(x’Hx) + tr(f’x) s.t. Ax = 0
-
lfd.registration.tps.tps_apply_kernel(distmat, dim)[source]¶ - if d=2:
- k(r) = 4 * r^2 log(r)
- d=3:
- k(r) = -r
import numpy as np, scipy.spatial.distance as ssd x = np.random.rand(100,2) d=ssd.squareform(ssd.pdist(x)) print np.clip(np.linalg.eigvalsh( 4 * d**2 * log(d+1e-9) ),0,inf).mean() print np.clip(np.linalg.eigvalsh(-d),0,inf).mean()
Note the actual coefficients (from http://www.geometrictools.com/Documentation/ThinPlateSplines.pdf) d=2: 1/(8*sqrt(pi)) = 0.070523697943469535 d=3: gamma(-.5)/(16*pi**1.5) = -0.039284682964880184
-
lfd.registration.tps.tps_fit3(x_na, y_ng, bend_coef, rot_coef, wt_n, ret_factorization=False)[source]¶
-
lfd.registration.tps.tps_rpm(x_nd, y_md, f_solver_factory=None, n_iter=20, em_iter=1, reg_init=0.1, reg_final=0.0001, rad_init=0.01, rad_final=0.0001, rot_reg=<Mock id='139893060503440'>, outlierprior=0.1, outlierfrac=0.01, prior_prob_nm=None, callback=None, args=())[source]¶
-
lfd.registration.tps.tps_rpm_bij(x_nd, y_md, f_solver_factory=None, g_solver_factory=None, n_iter=20, em_iter=1, reg_init=0.1, reg_final=0.0001, rad_init=0.01, rad_final=0.0001, rot_reg=<Mock id='139893060503440'>, outlierprior=0.1, outlierfrac=0.01, prior_prob_nm=None, callback=None, args=())[source]¶
lfd.registration.tps_experimental module¶
-
class
lfd.registration.tps_experimental.ThinPlateSpline(x_la, ctrl_na, g=None)[source]¶ Bases:
lfd.registration.transformation.Transformation-
x_na¶ centers of basis functions
-
w_ng¶ weights of basis functions
-
lin_ag¶ transpose of linear part, so you take x_na.dot(lin_ag)
-
trans_g¶ translation part
-
static
compute_N(ctrl_na)[source]¶ Computes change of variable matrix
The matrix
changes from
to
,
such that the affine part of
remains unchanged and the
non-affine part
satisfies the TPS constraint,
Parameters: ctrl_na – control points, 
Returns: change of variable matrix, 
Return type: N_bn Example
>>> import numpy as np >>> from lfd.registration.tps_experimental import ThinPlateSpline >>> n = 100 >>> a = 3 >>> g = 3 >>> ctrl_na = np.random.random((n, a)) >>> z_ng = np.random.random((n, g)) >>> N_bn = ThinPlateSpline.compute_N(ctrl_na) >>> theta_bg = N_bn.dot(z_ng) >>> trans_g = theta_bg[0] >>> lin_ag = theta_bg[1:a+1] >>> w_ng = theta_bg[a+1:] >>> print np.allclose(trans_g, z_ng[0]) True >>> print np.allclose(lin_ag, z_ng[1:a+1]) True >>> print np.allclose(ctrl_na.T.dot(w_ng), np.zeros((a, g))) True >>> print np.allclose(np.ones((n, 1)).T.dot(w_ng), np.zeros((1, g))) True
-
compute_transform_grad(x_ma=None)[source]¶ Gradient of the transform of the x_ma points. If x_ma is not specified, the source points x_la are used.
-
lin_ag
-
theta_bg¶ Can get theta_bg but not set it due to change of variables
-
trans_g
-
transform_points(x_ma=None)[source]¶ Transforms the x_ma points. If x_ma is not specified, the source points x_la are used.
-
w_ng Can get w_ng but not set it due to change of variables
-
z_ng¶
-
-
class
lfd.registration.tps_experimental.ThinPlateSplineNormal(x_la, u_ra, z_ra, x_ctrl_na, u_ctrl_ta, z_ctrl_ta, g=None)[source]¶ Bases:
lfd.registration.transformation.Transformation-
x_na¶ centers of basis functions
-
w_ng¶ weights of basis functions
-
lin_ag¶ transpose of linear part, so you take x_na.dot(lin_ag)
-
trans_g¶ translation part
-
static
compute_N(x_ctrl_na, u_ctrl_ta)[source]¶ Computes change of variable matrix
The matrix
changes from
to
,
such that the affine part of
remains unchanged and the
non-affine part
satisfies the TPSN constraint,![[X^\top U^\top] A &= 0 \\
[1^\top 0^\top] A &= 0](_images/math/3849028d578100ef5b812cc3b1e14db28c2aa445.png)
Parameters: - x_ctrl_na – control points,

- u_ctrl_ta – control normals,

Returns: change of variable matrix,

Return type: N_bn
- x_ctrl_na – control points,
-
compute_transform_grad(x_ma=None)[source]¶ Gradient of the transform of the x_ma points. If x_ma is not specified, the source points x_la are used.
-
lin_ag
-
theta_bg¶ Can get theta_bg but not set it due to change of variables
-
trans_g
-
transform_bases(x_ma, rot_mad, orthogonalize=True, orth_method='cross')[source]¶ orthogonalize: none, svd, qr
-
transform_points(x_ma=None)[source]¶ Transforms the x_ma points. If x_ma is not specified, the source points x_la are used.
-
w_eg¶ Can get w_ng but not set it due to change of variables
-
z_eg¶
-
-
lfd.registration.tps_experimental.compute_sum_var_matrix(f_k, p_ktd, w_t=None)[source]¶ Computes the kt by kn matrix L_ktkn for calculating the sum of variances.
- The sum of variances is given by
- (1/k) * np.sum(np.square(L_ktkn.dot(z_knd.reshape((-1,d)))))
-
lfd.registration.tps_experimental.l2_obj(x_nd, y_md, rad)[source]¶ Compute the L2 distance between the two Gaussian mixture densities constructed from a moving ‘model’ point set and a fixed ‘scene’ point set at a given ‘scale’. The term that only involves the fixed ‘scene’ is excluded from the returned distance. The gradient with respect to the ‘model’ is calculated and returned as well.
-
lfd.registration.tps_experimental.pairwise_tps_l2_cov(x_kld, y_md, p_ktd, ctrl_knd=None, f_init_k=None, n_iter=4, opt_iter=100, reg_init=0.1, reg_final=0.01, rad_init=0.1, rad_final=0.01, rot_reg=<Mock id='139893060503568'>, cov_coef=0.1, w_t=None, callback=None, args=(), multi_callback=None, multi_args=())[source]¶
-
lfd.registration.tps_experimental.pairwise_tps_l2_cov_obj(z_knd, f_k, y_md, p_ktd, rad, reg, rot_reg, cov_coef, L_ktkn=None, w_t=None)[source]¶
-
lfd.registration.tps_experimental.solve_qp(H, f)[source]¶ solve unconstrained qp min .5 tr(x’Hx) + tr(f’x)
-
lfd.registration.tps_experimental.tps_l2(x_ld, y_md, ctrl_nd=None, n_iter=4, opt_iter=100, reg_init=0.1, reg_final=0.01, rad_init=0.1, rad_final=0.01, rot_reg=<Mock id='139893060503568'>, callback=None, args=())[source]¶ TODO: default parameters
-
lfd.registration.tps_experimental.tpsn_kernel_matrix2(x_la, u_ra, z_ra, x_ctrl_na, u_ctrl_ta, z_ctrl_ta)[source]¶
-
lfd.registration.tps_experimental.tpsn_kernel_matrix2_0(x_la, x_ctrl_na, u_ctrl_ta, z_ctrl_ta)[source]¶
-
lfd.registration.tps_experimental.tpsn_kernel_matrix2_1(u_ra, z_ra, x_ctrl_na, u_ctrl_ta, z_ctrl_ta)[source]¶
-
lfd.registration.tps_experimental.tpsn_rpm(x_ld, u_rd, z_rd, y_md, v_sd, z_sd, n_iter=20, em_iter=1, reg_init=0.1, reg_final=0.0001, rad_init=0.01, rad_final=0.0001, radn_init=0.005, radn_final=0.001, nu_init=0.1, nu_final=10, rot_reg=<Mock id='139893060503440'>, outlierprior=0.1, outlierfrac=0.01, callback=None, args=())[source]¶ TODO: hyperparameters
lfd.registration.transformation module¶
Register point clouds to each other
arrays are named like name_abc abc are subscripts and indicate the what that tensor index refers to
- index name conventions:
- m: test point index n: training point index a: input coordinate g: output coordinate d: gripper coordinate
-
class
lfd.registration.transformation.Transformation[source]¶ Bases:
objectObject oriented interface for transformations R^d -> R^d












