comparison projective_transformation_points.py @ 5:3a686b6aa7fc draft

"planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tools/projective_transformation_points/ commit c4424f5dd4110c92ae39815ebfe2ea8c1010be9c"
author imgteam
date Wed, 26 Jan 2022 15:25:38 +0000
parents aaac58d83043
children
comparison
equal deleted inserted replaced
4:aaac58d83043 5:3a686b6aa7fc
1 from skimage.transform import ProjectiveTransform 1 """
2 from scipy.ndimage import map_coordinates 2 Copyright 2019-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
3 import numpy as np 11 import numpy as np
4 import pandas as pd 12 import pandas as pd
5 import argparse 13 from scipy.ndimage import map_coordinates
14 from skimage.transform import ProjectiveTransform
6 15
7 16
8 def _stackcopy(a, b): 17 def _stackcopy(a, b):
9 if a.ndim == 3: 18 if a.ndim == 3:
10 a[:] = b[:, :, np.newaxis] 19 a[:] = b[:, :, np.newaxis]
19 coords_shape.append(shape[2]) 28 coords_shape.append(shape[2])
20 coords = np.empty(coords_shape, dtype=dtype) 29 coords = np.empty(coords_shape, dtype=dtype)
21 30
22 tf_coords = np.indices((cols, rows), dtype=dtype).reshape(2, -1).T 31 tf_coords = np.indices((cols, rows), dtype=dtype).reshape(2, -1).T
23 32
24 for i in range(0, (tf_coords.shape[0]//batch_size+1)): 33 for i in range(0, (tf_coords.shape[0] // batch_size + 1)):
25 tf_coords[batch_size*i:batch_size*(i+1)] = coord_map(tf_coords[batch_size*i:batch_size*(i+1)]) 34 tf_coords[batch_size * i:batch_size * (i + 1)] = coord_map(tf_coords[batch_size * i:batch_size * (i + 1)])
26 tf_coords = tf_coords.T.reshape((-1, cols, rows)).swapaxes(1, 2) 35 tf_coords = tf_coords.T.reshape((-1, cols, rows)).swapaxes(1, 2)
27 36
28 _stackcopy(coords[1, ...], tf_coords[0, ...]) 37 _stackcopy(coords[1, ...], tf_coords[0, ...])
29 _stackcopy(coords[0, ...], tf_coords[1, ...]) 38 _stackcopy(coords[0, ...], tf_coords[1, ...])
30 if len(shape) == 3: 39 if len(shape) == 3:
34 43
35 44
36 def warp_coords_batch(coord_map, coords, dtype=np.float64, batch_size=1000000): 45 def warp_coords_batch(coord_map, coords, dtype=np.float64, batch_size=1000000):
37 tf_coords = coords.astype(np.float32)[:, ::-1] 46 tf_coords = coords.astype(np.float32)[:, ::-1]
38 47
39 for i in range(0, (tf_coords.shape[0]//batch_size)+1): 48 for i in range(0, (tf_coords.shape[0] // batch_size) + 1):
40 tf_coords[batch_size*i:batch_size*(i+1)] = coord_map(tf_coords[batch_size*i:batch_size*(i+1)]) 49 tf_coords[batch_size * i:batch_size * (i + 1)] = coord_map(tf_coords[batch_size * i:batch_size * (i + 1)])
41 50
42 return tf_coords[:, ::-1] 51 return tf_coords[:, ::-1]
43 52
44 53
45 def transform(fn_roi_coords, fn_warp_matrix, fn_out): 54 def transform(fn_roi_coords, fn_warp_matrix, fn_out):
46 data = pd.read_csv(fn_roi_coords, delimiter="\t") 55 data = pd.read_csv(fn_roi_coords, delimiter="\t")
47 all_data = np.array(data) 56 all_data = np.array(data)
48 57
49 nrows = all_data.shape[0] 58 nrows, ncols = all_data.shape[0:2]
50 ncols = all_data.shape[1] 59 roi_coords = all_data.take([0, 1], axis=1).astype('int64')
51 roi_coords = all_data.take([0,1],axis=1).astype('int64') 60
52
53 tol = 10 61 tol = 10
54 moving = np.zeros(np.max(roi_coords,axis=0)+tol, dtype=np.uint32) 62 moving = np.zeros(np.max(roi_coords, axis=0) + tol, dtype=np.uint32)
55 idx_roi_coords = (roi_coords[:,0]-1) * moving.shape[1] + roi_coords[:,1] - 1 63 idx_roi_coords = (roi_coords[:, 0] - 1) * moving.shape[1] + roi_coords[:, 1] - 1
56 moving.flat[idx_roi_coords] = np.transpose(np.arange(nrows)+1) 64 moving.flat[idx_roi_coords] = np.transpose(np.arange(nrows) + 1)
57 65
58 trans_matrix = np.array(pd.read_csv(fn_warp_matrix, delimiter="\t", header=None)) 66 trans_matrix = np.array(pd.read_csv(fn_warp_matrix, delimiter="\t", header=None))
59 transP = ProjectiveTransform(matrix=trans_matrix) 67 transP = ProjectiveTransform(matrix=trans_matrix)
60 roi_coords_warped_direct = warp_coords_batch(transP, roi_coords) 68 roi_coords_warped_direct = warp_coords_batch(transP, roi_coords)
61 shape_fixed = np.round(np.max(roi_coords_warped_direct,axis=0)).astype(roi_coords.dtype)+tol 69 shape_fixed = np.round(np.max(roi_coords_warped_direct, axis=0)).astype(roi_coords.dtype) + tol
62 70
63 transI = ProjectiveTransform(matrix=np.linalg.inv(trans_matrix)) 71 transI = ProjectiveTransform(matrix=np.linalg.inv(trans_matrix))
64 img_coords_warped = warp_img_coords_batch(transI, shape_fixed) 72 img_coords_warped = warp_img_coords_batch(transI, shape_fixed)
65 73
66 moving_warped = map_coordinates(moving, img_coords_warped, order=0, mode='constant', cval=0) 74 moving_warped = map_coordinates(moving, img_coords_warped, order=0, mode='constant', cval=0)
67 idx_roi_coords_warped = np.where(moving_warped>0) 75 idx_roi_coords_warped = np.where(moving_warped > 0)
68 roi_annots_warped = moving_warped.compress((moving_warped>0).flat) 76 roi_annots_warped = moving_warped.compress((moving_warped > 0).flat)
69 77
70 df = pd.DataFrame() 78 df = pd.DataFrame()
71 col_names = data.columns.tolist() 79 col_names = data.columns.tolist()
72 df['x'] = idx_roi_coords_warped[0] + 1 80 df['x'] = idx_roi_coords_warped[0] + 1
73 df['y'] = idx_roi_coords_warped[1] + 1 81 df['y'] = idx_roi_coords_warped[1] + 1
74 if ncols>2: 82 if ncols > 2:
75 for i in range(2,ncols): 83 for i in range(2, ncols):
76 df[col_names[i]] = all_data[:,i].take(roi_annots_warped) 84 df[col_names[i]] = all_data[:, i].take(roi_annots_warped - 1)
77 df.to_csv(fn_out, index = False, sep="\t") 85 df.to_csv(fn_out, index=False, sep="\t")
78 86
79 87
80 if __name__ == "__main__": 88 if __name__ == "__main__":
81 parser = argparse.ArgumentParser(description="Transform coordinates") 89 parser = argparse.ArgumentParser(description="Transform ROIs defined by pixel (point) coordinates")
82 parser.add_argument("coords", help="Paste path to .csv with coordinates (and labels) to transform (tab separated)") 90 parser.add_argument("coords", help="Path to the TSV file of the coordinates (and labels) to be transformed")
83 parser.add_argument("warp_matrix", help="Paste path to .csv that should be used for transformation (tab separated)") 91 parser.add_argument("tmat", help="Path to the TSV file of the transformation matrix")
84 parser.add_argument("out", help="Paste path to file in which transformed coords (and labels) should be saved (tab separated)") 92 parser.add_argument("out", help="Path to the TSV file of the transformed coordinates (and labels)")
85 args = parser.parse_args() 93 args = parser.parse_args()
86 transform(args.coords, args.warp_matrix, args.out) 94 transform(args.coords, args.tmat, args.out)