Mercurial > repos > imgteam > landmark_registration
comparison landmark_registration.py @ 2:4e089a0983b1 draft
"planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tools/landmark_registration/ commit 927b78d47c31714776ccdf3d16f26c3779298abb"
author | imgteam |
---|---|
date | Sun, 20 Feb 2022 15:46:58 +0000 |
parents | b0503eec7bd6 |
children | aee73493bf53 |
comparison
equal
deleted
inserted
replaced
1:b0503eec7bd6 | 2:4e089a0983b1 |
---|---|
1 """ | |
2 Copyright 2017-2022 Biomedical Computer Vision Group, Heidelberg University. | |
3 | |
4 Distributed under the MIT license. | |
5 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | |
6 | |
7 """ | |
8 | |
9 import argparse | |
10 | |
11 import numpy as np | |
12 import pandas as pd | |
13 from scipy.linalg import lstsq | |
1 from skimage.measure import ransac | 14 from skimage.measure import ransac |
2 from skimage.transform import AffineTransform | 15 from skimage.transform import AffineTransform |
3 import pandas as pd | |
4 import numpy as np | |
5 import argparse | |
6 | 16 |
7 def landmark_registration(points_file1, points_file2, out_file, residual_threshold=2, max_trials=100, delimiter="\t"): | |
8 points1 = pd.read_csv(points_file1, delimiter=delimiter) | |
9 points2 = pd.read_csv(points_file2, delimiter=delimiter) | |
10 | 17 |
11 src = np.concatenate([np.array(points1['x']).reshape([-1,1]), np.array(points1['y']).reshape([-1,1])], axis=-1) | 18 def landmark_registration(pts_f1, pts_f2, out_f, res_th=None, max_ite=None, delimiter="\t"): |
12 dst = np.concatenate([np.array(points2['x']).reshape([-1,1]), np.array(points2['y']).reshape([-1,1])], axis=-1) | |
13 | 19 |
14 model = AffineTransform() | 20 points1 = pd.read_csv(pts_f1, delimiter=delimiter) |
15 model_robust, inliers = ransac((src, dst), AffineTransform, min_samples=3, | 21 points2 = pd.read_csv(pts_f2, delimiter=delimiter) |
16 residual_threshold=residual_threshold, max_trials=max_trials) | 22 |
17 pd.DataFrame(model_robust.params).to_csv(out_file, header=None, index=False, sep="\t") | 23 src = np.concatenate([np.array(points1['x']).reshape([-1, 1]), |
24 np.array(points1['y']).reshape([-1, 1])], | |
25 axis=-1) | |
26 dst = np.concatenate([np.array(points2['x']).reshape([-1, 1]), | |
27 np.array(points2['y']).reshape([-1, 1])], | |
28 axis=-1) | |
29 | |
30 if res_th is not None and max_ite is not None: | |
31 model_robust, inliers = ransac((src, dst), AffineTransform, min_samples=3, residual_threshold=res_th, max_trials=max_ite) | |
32 pd.DataFrame(model_robust.params).to_csv(out_f, header=None, index=False, sep="\t") | |
33 | |
34 else: | |
35 A = np.zeros((src.size, 6)) | |
36 A[0:src.shape[0], [0, 1]] = src | |
37 A[0:src.shape[0], 2] = 1 | |
38 A[src.shape[0]:, [3, 4]] = src | |
39 A[src.shape[0]:, 5] = 1 | |
40 b = dst.T.flatten().astype('float64') | |
41 x = lstsq(A, b) | |
42 | |
43 tmat = np.eye(3) | |
44 tmat[0, :] = x[0].take([0, 1, 2]) | |
45 tmat[1, :] = x[0].take([3, 4, 5]) | |
46 pd.DataFrame(tmat).to_csv(out_f, header=None, index=False, sep="\t") | |
47 | |
18 | 48 |
19 if __name__ == "__main__": | 49 if __name__ == "__main__": |
20 parser = argparse.ArgumentParser(description="Estimate transformation from points") | 50 parser = argparse.ArgumentParser(description="Estimate affine transformation matrix based on landmark coordinates") |
21 parser.add_argument("points_file1", help="Paste path to src points") | 51 parser.add_argument("fn_pts1", help="Coordinates of SRC landmarks (tsv file)") |
22 parser.add_argument("points_file2", help="Paste path to dst points") | 52 parser.add_argument("fn_pts2", help="Coordinates of DST landmarks (tsv file)") |
23 parser.add_argument("warp_matrix", help="Paste path to warp_matrix.csv that should be used for transformation") | 53 parser.add_argument("fn_tmat", help="Path the output (transformation matrix)") |
24 parser.add_argument("--residual_threshold", dest="residual_threshold", help="Maximum distance for a data point to be classified as an inlier.", type=float, default=2) | 54 parser.add_argument("--res_th", dest="res_th", type=float, help="Maximum distance for a data point to be classified as an inlier") |
25 parser.add_argument("--max_trials", dest="max_trials", help="Maximum number of iterations for random sample selection.", type=int, default=100) | 55 parser.add_argument("--max_ite", dest="max_ite", type=int, help="Maximum number of iterations for random sample selection") |
26 args = parser.parse_args() | 56 args = parser.parse_args() |
27 landmark_registration(args.points_file1, args.points_file2, args.warp_matrix, residual_threshold=args.residual_threshold, max_trials=args.max_trials) | 57 |
58 res_th = None | |
59 if args.res_th: | |
60 res_th = args.res_th | |
61 max_ite = None | |
62 if args.max_ite: | |
63 max_ite = args.max_ite | |
64 | |
65 landmark_registration(args.fn_pts1, args.fn_pts2, args.fn_tmat, res_th=res_th, max_ite=max_ite) |