diff --git a/tools/orientationpy/.shed.yml b/tools/orientationpy/.shed.yml new file mode 100644 index 00000000..6219470f --- /dev/null +++ b/tools/orientationpy/.shed.yml @@ -0,0 +1,8 @@ +categories: + - Imaging +description: Compute image orientation +long_description: Compute image orientation based on OrientationPy. +name: orientationpy +owner: imgteam +homepage_url: https://github.com/bmcv +remote_repository_url: https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/orientationpy \ No newline at end of file diff --git a/tools/orientationpy/orientationpy-cli.py b/tools/orientationpy/orientationpy-cli.py new file mode 100644 index 00000000..955fb7d5 --- /dev/null +++ b/tools/orientationpy/orientationpy-cli.py @@ -0,0 +1,54 @@ +import argparse +import csv + +import numpy as np +import orientationpy +import skimage.io +import skimage.util + + +if __name__ == '__main__': + + parser = argparse.ArgumentParser() + parser.add_argument('input', type=str) + parser.add_argument('--mode', type=str, required=True) + parser.add_argument('--sigma', type=float, required=True) + parser.add_argument('--min_coherency', type=float, required=True) + parser.add_argument('--min_energy', type=float, required=True) + parser.add_argument('--max_precision', type=int, required=True) + parser.add_argument('--output_angle_tsv', type=str, default=None) + args = parser.parse_args() + + im = skimage.io.imread(args.input) + im = skimage.util.img_as_float(im) + im = np.squeeze(im) + assert im.ndim == 2 + + Gy, Gx = orientationpy.computeGradient(im, mode=args.mode) + structureTensor = orientationpy.computeStructureTensor([Gy, Gx], sigma=args.sigma) + orientations = orientationpy.computeOrientation(structureTensor, computeEnergy=True, computeCoherency=True) + + # Compute angle according to https://bigwww.epfl.ch/demo/orientationj/#dist: + mask = np.logical_and( + orientations['coherency'] >= args.min_coherency, + orientations['energy'] >= args.min_energy * orientations['energy'].max(), + ) + angles = orientations['theta'][mask] + weights = orientations['coherency'][mask] + bin_size = 1 if args.max_precision == 0 else pow(10, -args.max_precision) + hist, bin_edges = np.histogram( + angles, + range=(-90, +90), + weights=weights, + bins=round(180 / bin_size), + ) + hidx = np.argmax(hist) + angle = (bin_edges[hidx] + bin_edges[hidx + 1]) / 2 + angle = round(angle, args.max_precision) + + # Write results + if args.output_angle_tsv: + with open(args.output_angle_tsv, 'w') as fp: + writer = csv.writer(fp, delimiter='\t', lineterminator='\n') + writer.writerow(['Angle']) + writer.writerow([angle]) diff --git a/tools/orientationpy/orientationpy.xml b/tools/orientationpy/orientationpy.xml new file mode 100644 index 00000000..106f4c4a --- /dev/null +++ b/tools/orientationpy/orientationpy.xml @@ -0,0 +1,97 @@ + + with OrientationPy + + 0.2.0.4 + 0 + + + operation_3443 + + + orientationj + + + orientationpy + scikit-image + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Compute the orientation of 2-D images in degrees using OrientationPy. + + OrientationPy is the pythonic successor to the well-loved OrientationJ Fiji Plugin. + It is a library that takes in images and computes the orientation of the greylevels. + A key step is the computation of image gradients, for a number of different techniques is supported. + + For more information on ``--min_energy`` and ``--min_coherency`` see: https://epfl-center-for-imaging.gitlab.io/orientationpy/orientationpy_examples/plot_fibres_2d.html#plot-hsv-composition + + + 10.1007/s10237-011-0325-z + + diff --git a/tools/orientationpy/test-data/input1.tif b/tools/orientationpy/test-data/input1.tif new file mode 100644 index 00000000..203bc1bb Binary files /dev/null and b/tools/orientationpy/test-data/input1.tif differ diff --git a/tools/orientationpy/test-data/input2.tif b/tools/orientationpy/test-data/input2.tif new file mode 100644 index 00000000..2e52fea5 Binary files /dev/null and b/tools/orientationpy/test-data/input2.tif differ