# HG changeset patch # User imgteam # Date 1643210738 0 # Node ID 3a686b6aa7fcc3c10ea7c2045a3f5e8e3e209deb # Parent aaac58d830436b1721a40c48174fb590dbddde00 "planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tools/projective_transformation_points/ commit c4424f5dd4110c92ae39815ebfe2ea8c1010be9c" diff -r aaac58d83043 -r 3a686b6aa7fc projective_transformation_points.py --- a/projective_transformation_points.py Wed Dec 23 23:56:29 2020 +0000 +++ b/projective_transformation_points.py Wed Jan 26 15:25:38 2022 +0000 @@ -1,8 +1,17 @@ -from skimage.transform import ProjectiveTransform -from scipy.ndimage import map_coordinates +""" +Copyright 2019-2022 Biomedical Computer Vision Group, Heidelberg University. + +Distributed under the MIT license. +See file LICENSE for detail or copy at https://opensource.org/licenses/MIT + +""" + +import argparse + import numpy as np import pandas as pd -import argparse +from scipy.ndimage import map_coordinates +from skimage.transform import ProjectiveTransform def _stackcopy(a, b): @@ -21,8 +30,8 @@ tf_coords = np.indices((cols, rows), dtype=dtype).reshape(2, -1).T - for i in range(0, (tf_coords.shape[0]//batch_size+1)): - tf_coords[batch_size*i:batch_size*(i+1)] = coord_map(tf_coords[batch_size*i:batch_size*(i+1)]) + for i in range(0, (tf_coords.shape[0] // batch_size + 1)): + tf_coords[batch_size * i:batch_size * (i + 1)] = coord_map(tf_coords[batch_size * i:batch_size * (i + 1)]) tf_coords = tf_coords.T.reshape((-1, cols, rows)).swapaxes(1, 2) _stackcopy(coords[1, ...], tf_coords[0, ...]) @@ -36,51 +45,50 @@ def warp_coords_batch(coord_map, coords, dtype=np.float64, batch_size=1000000): tf_coords = coords.astype(np.float32)[:, ::-1] - for i in range(0, (tf_coords.shape[0]//batch_size)+1): - tf_coords[batch_size*i:batch_size*(i+1)] = coord_map(tf_coords[batch_size*i:batch_size*(i+1)]) + for i in range(0, (tf_coords.shape[0] // batch_size) + 1): + tf_coords[batch_size * i:batch_size * (i + 1)] = coord_map(tf_coords[batch_size * i:batch_size * (i + 1)]) return tf_coords[:, ::-1] - + def transform(fn_roi_coords, fn_warp_matrix, fn_out): data = pd.read_csv(fn_roi_coords, delimiter="\t") all_data = np.array(data) - - nrows = all_data.shape[0] - ncols = all_data.shape[1] - roi_coords = all_data.take([0,1],axis=1).astype('int64') - + + nrows, ncols = all_data.shape[0:2] + roi_coords = all_data.take([0, 1], axis=1).astype('int64') + tol = 10 - moving = np.zeros(np.max(roi_coords,axis=0)+tol, dtype=np.uint32) - idx_roi_coords = (roi_coords[:,0]-1) * moving.shape[1] + roi_coords[:,1] - 1 - moving.flat[idx_roi_coords] = np.transpose(np.arange(nrows)+1) - + moving = np.zeros(np.max(roi_coords, axis=0) + tol, dtype=np.uint32) + idx_roi_coords = (roi_coords[:, 0] - 1) * moving.shape[1] + roi_coords[:, 1] - 1 + moving.flat[idx_roi_coords] = np.transpose(np.arange(nrows) + 1) + trans_matrix = np.array(pd.read_csv(fn_warp_matrix, delimiter="\t", header=None)) transP = ProjectiveTransform(matrix=trans_matrix) roi_coords_warped_direct = warp_coords_batch(transP, roi_coords) - shape_fixed = np.round(np.max(roi_coords_warped_direct,axis=0)).astype(roi_coords.dtype)+tol - + shape_fixed = np.round(np.max(roi_coords_warped_direct, axis=0)).astype(roi_coords.dtype) + tol + transI = ProjectiveTransform(matrix=np.linalg.inv(trans_matrix)) img_coords_warped = warp_img_coords_batch(transI, shape_fixed) - + moving_warped = map_coordinates(moving, img_coords_warped, order=0, mode='constant', cval=0) - idx_roi_coords_warped = np.where(moving_warped>0) - roi_annots_warped = moving_warped.compress((moving_warped>0).flat) - + idx_roi_coords_warped = np.where(moving_warped > 0) + roi_annots_warped = moving_warped.compress((moving_warped > 0).flat) + df = pd.DataFrame() col_names = data.columns.tolist() df['x'] = idx_roi_coords_warped[0] + 1 df['y'] = idx_roi_coords_warped[1] + 1 - if ncols>2: - for i in range(2,ncols): - df[col_names[i]] = all_data[:,i].take(roi_annots_warped) - df.to_csv(fn_out, index = False, sep="\t") + if ncols > 2: + for i in range(2, ncols): + df[col_names[i]] = all_data[:, i].take(roi_annots_warped - 1) + df.to_csv(fn_out, index=False, sep="\t") if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Transform coordinates") - parser.add_argument("coords", help="Paste path to .csv with coordinates (and labels) to transform (tab separated)") - parser.add_argument("warp_matrix", help="Paste path to .csv that should be used for transformation (tab separated)") - parser.add_argument("out", help="Paste path to file in which transformed coords (and labels) should be saved (tab separated)") + parser = argparse.ArgumentParser(description="Transform ROIs defined by pixel (point) coordinates") + parser.add_argument("coords", help="Path to the TSV file of the coordinates (and labels) to be transformed") + parser.add_argument("tmat", help="Path to the TSV file of the transformation matrix") + parser.add_argument("out", help="Path to the TSV file of the transformed coordinates (and labels)") args = parser.parse_args() - transform(args.coords, args.warp_matrix, args.out) + transform(args.coords, args.tmat, args.out) diff -r aaac58d83043 -r 3a686b6aa7fc projective_transformation_points.xml --- a/projective_transformation_points.xml Wed Dec 23 23:56:29 2020 +0000 +++ b/projective_transformation_points.xml Wed Jan 26 15:25:38 2022 +0000 @@ -1,5 +1,5 @@ - - of input points + + of ROIs defined by pixel (point) coordinates scikit-image scipy @@ -7,32 +7,39 @@ numpy tifffile - + - - + + - + - - - + + + **What it does** - This tool performs a projective transformation of the input (moving) points (with/without labels). + This tool performs a projective transformation of regions of interest (ROIs) defined by pixel (point) coordinates with/without labels. + + About the format of point coordinates (and labels) in the input TSV table: + 1st column: x-coordinate; + 2nd column: y-coordinate; + (optional) more column(s): point label(s) (numerical or categorical). + The top row of the table will be regarded as column headers. + 10.1016/j.jbiotec.2017.07.019 diff -r aaac58d83043 -r 3a686b6aa7fc test-data/in.tabular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/in.tabular Wed Jan 26 15:25:38 2022 +0000 @@ -0,0 +1,10 @@ +x y tissue_type ROI_ID +11 49 tumor 1 +11 50 stroma 1 +11 51 tumor 2 +11 52 tumor 2 +12 49 tumor 1 +12 50 stroma 1 +12 51 tumor 2 +12 52 tumor 2 +13 49 tumor 1 diff -r aaac58d83043 -r 3a686b6aa7fc test-data/out.tabular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/out.tabular Wed Jan 26 15:25:38 2022 +0000 @@ -0,0 +1,10 @@ +x y tissue_type ROI_ID +111 99 tumor 1 +111 100 stroma 1 +111 101 tumor 2 +111 102 tumor 2 +112 99 tumor 1 +112 100 stroma 1 +112 101 tumor 2 +112 102 tumor 2 +113 99 tumor 1 diff -r aaac58d83043 -r 3a686b6aa7fc test-data/out.tsv --- a/test-data/out.tsv Wed Dec 23 23:56:29 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -x y -28 14 -28 15 -28 16 -28 17 -30 12 -35 25 diff -r aaac58d83043 -r 3a686b6aa7fc test-data/points_tsv.tsv --- a/test-data/points_tsv.tsv Wed Dec 23 23:56:29 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -5 3 -10 2 -8 4 -15 15 -8 5 -8 6 -8 7 diff -r aaac58d83043 -r 3a686b6aa7fc test-data/tmat.tabular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/tmat.tabular Wed Jan 26 15:25:38 2022 +0000 @@ -0,0 +1,3 @@ +1.0 0.0 50 +0.0 1.0 100 +0.0 0.0 1.0 diff -r aaac58d83043 -r 3a686b6aa7fc test-data/warp_matrix.tsv --- a/test-data/warp_matrix.tsv Wed Dec 23 23:56:29 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -1 0 10 -0 1 20 -0 0 1