Skip to content

Commit

Permalink
Updated the description of tool "projective_transformation_points" (#32)
Browse files Browse the repository at this point in the history
* Updated tool "projective_transformation_points": bug fix, new description, new test data

* Updated license info
  • Loading branch information
qgao-hd authored Jan 26, 2022
1 parent ee37254 commit c4424f5
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 65 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2016
Copyright (c) 2016-2022 Biomedical Computer Vision Group, Heidelberg University

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
4 changes: 2 additions & 2 deletions tools/projective_transformation_points/.shed.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
categories:
- Imaging
description: Projective transformation - Points
long_description: This tool performs a projective transformation of input coordinates with a warp matrix.
description: Projective transformation of ROIs defined by pixel (point) coordinates
long_description: This tool performs a projective transformation of regions of interest (ROIs) defined by pixel (point) coordinates based on a given transformation matrix.
name: projective_transformation_points
owner: imgteam
homepage_url: https://github.com/bmcv
Expand Down
Original file line number Diff line number Diff line change
@@ -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):
Expand All @@ -21,8 +30,8 @@ def warp_img_coords_batch(coord_map, shape, dtype=np.float64, batch_size=1000000

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, ...])
Expand All @@ -36,51 +45,50 @@ def warp_img_coords_batch(coord_map, shape, dtype=np.float64, batch_size=1000000
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)
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
<tool id="ip_projective_transformation_points" name="Projective Transformation" version="0.1.0">
<description>of input points</description>
<tool id="ip_projective_transformation_points" name="Projective Transformation" license="MIT" version="0.1.1" profile="20.05">
<description>of ROIs defined by pixel (point) coordinates</description>
<requirements>
<requirement type="package" version="0.14.2">scikit-image</requirement>
<requirement type="package" version="1.2.1">scipy</requirement>
<requirement type="package" version="0.23.4">pandas</requirement>
<requirement type="package" version="1.15.2">numpy</requirement>
<requirement type="package" version="0.15.1">tifffile</requirement>
</requirements>
<command>
<command detect_errors="aggressive">
<![CDATA[
python '$__tool_directory__/projective_transformation_points.py'
'$moving_points'
'$warp_matrix'
'$out'
'$input'
'$tmat'
'$output'
]]>
</command>
<inputs>
<param name="moving_points" type="data" format="tabular" label="Moving Points" />
<param name="warp_matrix" type= "data" format="tabular" label="Warp Matrix" />
<param name="input" type="data" format="tabular" label="ROIs (pixel coordinates) to be transformed (TSV file)" />
<param name="tmat" type= "data" format="tabular" label="Transformation matrix (TSV file)" />
</inputs>
<outputs>
<data format="tabular" name="out" />
<data format="tabular" name="output" />
</outputs>
<tests>
<test>
<param name="moving_points" value="points_tsv.tsv" />
<param name="warp_matrix" value="warp_matrix.tsv" />
<output name="out" value="out.tsv" ftype="tabular" />
<param name="input" value="in.tabular" />
<param name="tmat" value="tmat.tabular" />
<output name="output" value="out.tabular" ftype="tabular" compare="diff" />
</test>
</tests>
<help>
**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.

</help>
<citations>
<citation type="doi">10.1016/j.jbiotec.2017.07.019</citation>
Expand Down
10 changes: 10 additions & 0 deletions tools/projective_transformation_points/test-data/in.tabular
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions tools/projective_transformation_points/test-data/out.tabular
Original file line number Diff line number Diff line change
@@ -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
7 changes: 0 additions & 7 deletions tools/projective_transformation_points/test-data/out.tsv

This file was deleted.

This file was deleted.

3 changes: 3 additions & 0 deletions tools/projective_transformation_points/test-data/tmat.tabular
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1.0 0.0 50
0.0 1.0 100
0.0 0.0 1.0

This file was deleted.

0 comments on commit c4424f5

Please sign in to comment.