Mercurial > repos > imgteam > imagej2_crop
comparison imagej2_analyze_skeleton_jython_script.py @ 0:db3066ae9b09 draft default tip
planemo upload for repository https://github.com/bgruening/galaxytools/tree/master/tools/image_processing/imagej2 commit 8f49f3c66b5a1de99ec15e65c2519a56792f1d56
| author | imgteam |
|---|---|
| date | Wed, 25 Sep 2024 16:28:45 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:db3066ae9b09 |
|---|---|
| 1 import math | |
| 2 import sys | |
| 3 | |
| 4 from ij import IJ | |
| 5 from sc.fiji.analyzeSkeleton import AnalyzeSkeleton_ | |
| 6 | |
| 7 BASIC_NAMES = [ | |
| 8 "Branches", | |
| 9 "Junctions", | |
| 10 "End-point Voxels", | |
| 11 "Junction Voxels", | |
| 12 "Slab Voxels", | |
| 13 "Average branch length", | |
| 14 "Triple Points", | |
| 15 "Quadruple Points", | |
| 16 "Maximum Branch Length", | |
| 17 ] | |
| 18 DETAIL_NAMES = [ | |
| 19 "Skeleton ID", | |
| 20 "Branch length", | |
| 21 "V1 x", | |
| 22 "V1 y", | |
| 23 "V1 z", | |
| 24 "V2 x", | |
| 25 "V2 y", | |
| 26 "V2 z", | |
| 27 "Euclidean distance", | |
| 28 ] | |
| 29 OPTIONS = ["edm=Overwrite", "iterations=1", "count=1"] | |
| 30 | |
| 31 | |
| 32 def get_euclidean_distance(vertex1, vertex2): | |
| 33 x1, y1, z1 = get_points(vertex1) | |
| 34 x2, y2, z2 = get_points(vertex2) | |
| 35 return math.sqrt( | |
| 36 math.pow((x2 - x1), 2) + math.pow((y2 - y1), 2) + math.pow((z2 - z1), 2) | |
| 37 ) | |
| 38 | |
| 39 | |
| 40 def get_graph_length(graph): | |
| 41 length = 0 | |
| 42 for edge in graph.getEdges(): | |
| 43 length = length + edge.getLength() | |
| 44 return length | |
| 45 | |
| 46 | |
| 47 def get_points(vertex): | |
| 48 # An array of Point, which has attributes x,y,z. | |
| 49 point = vertex.getPoints()[0] | |
| 50 return point.x, point.y, point.z | |
| 51 | |
| 52 | |
| 53 def get_sorted_edge_lengths(graph): | |
| 54 # Return graph edges sorted from longest to shortest. | |
| 55 edges = graph.getEdges() | |
| 56 edges = sorted(edges, key=lambda edge: edge.getLength(), reverse=True) | |
| 57 return edges | |
| 58 | |
| 59 | |
| 60 def get_sorted_graph_lengths(result): | |
| 61 # Get the separate graphs (skeletons). | |
| 62 graphs = result.getGraph() | |
| 63 # Sort graphs from longest to shortest. | |
| 64 graphs = sorted(graphs, key=lambda g: get_graph_length(g), reverse=True) | |
| 65 return graphs | |
| 66 | |
| 67 | |
| 68 def save(result, output, show_detailed_info, calculate_largest_shortest_path, sep="\t"): | |
| 69 num_trees = int(result.getNumOfTrees()) | |
| 70 outf = open(output, "wb") | |
| 71 outf.write("# %s\n" % sep.join(BASIC_NAMES)) | |
| 72 for index in range(num_trees): | |
| 73 outf.write("%d%s" % (result.getBranches()[index], sep)) | |
| 74 outf.write("%d%s" % (result.getJunctions()[index], sep)) | |
| 75 outf.write("%d%s" % (result.getEndPoints()[index], sep)) | |
| 76 outf.write("%d%s" % (result.getJunctionVoxels()[index], sep)) | |
| 77 outf.write("%d%s" % (result.getSlabs()[index], sep)) | |
| 78 outf.write("%.3f%s" % (result.getAverageBranchLength()[index], sep)) | |
| 79 outf.write("%d%s" % (result.getTriples()[index], sep)) | |
| 80 outf.write("%d%s" % (result.getQuadruples()[index], sep)) | |
| 81 outf.write("%.3f" % result.getMaximumBranchLength()[index]) | |
| 82 if calculate_largest_shortest_path: | |
| 83 outf.write("%s%.3f%s" % (sep, result.shortestPathList.get(index), sep)) | |
| 84 outf.write("%d%s" % (result.spStartPosition[index][0], sep)) | |
| 85 outf.write("%d%s" % (result.spStartPosition[index][1], sep)) | |
| 86 outf.write("%d\n" % result.spStartPosition[index][2]) | |
| 87 else: | |
| 88 outf.write("\n") | |
| 89 if show_detailed_info: | |
| 90 outf.write("# %s\n" % sep.join(DETAIL_NAMES)) | |
| 91 # The following index is a placeholder for the skeleton ID. | |
| 92 # The terms "graph" and "skeleton" refer to the same thing. | |
| 93 # Also, the SkeletonResult.java code states that the | |
| 94 # private Graph[] graph object is an array of graphs (one | |
| 95 # per tree). | |
| 96 for index, graph in enumerate(get_sorted_graph_lengths(result)): | |
| 97 for edge in get_sorted_edge_lengths(graph): | |
| 98 vertex1 = edge.getV1() | |
| 99 x1, y1, z1 = get_points(vertex1) | |
| 100 vertex2 = edge.getV2() | |
| 101 x2, y2, z2 = get_points(vertex2) | |
| 102 outf.write("%d%s" % (index + 1, sep)) | |
| 103 outf.write("%.3f%s" % (edge.getLength(), sep)) | |
| 104 outf.write("%d%s" % (x1, sep)) | |
| 105 outf.write("%d%s" % (y1, sep)) | |
| 106 outf.write("%d%s" % (z1, sep)) | |
| 107 outf.write("%d%s" % (x2, sep)) | |
| 108 outf.write("%d%s" % (y2, sep)) | |
| 109 outf.write("%d%s" % (z2, sep)) | |
| 110 outf.write("%.3f" % get_euclidean_distance(vertex1, vertex2)) | |
| 111 if calculate_largest_shortest_path: | |
| 112 # Keep number of separated items the same for each line. | |
| 113 outf.write("%s %s" % (sep, sep)) | |
| 114 outf.write(" %s" % sep) | |
| 115 outf.write(" %s" % sep) | |
| 116 outf.write(" \n") | |
| 117 else: | |
| 118 outf.write("\n") | |
| 119 outf.close() | |
| 120 | |
| 121 | |
| 122 # Fiji Jython interpreter implements Python 2.5 which does not | |
| 123 # provide support for argparse. | |
| 124 input = sys.argv[-7] | |
| 125 black_background = sys.argv[-6] == "yes" | |
| 126 prune_cycle_method = sys.argv[-5] | |
| 127 prune_ends = sys.argv[-4] == "yes" | |
| 128 calculate_largest_shortest_path = sys.argv[-3] == "yes" | |
| 129 if calculate_largest_shortest_path: | |
| 130 BASIC_NAMES.extend(["Longest Shortest Path", "spx", "spy", "spz"]) | |
| 131 DETAIL_NAMES.extend([" ", " ", " ", " "]) | |
| 132 show_detailed_info = sys.argv[-2] == "yes" | |
| 133 output = sys.argv[-1] | |
| 134 | |
| 135 # Open the input image file. | |
| 136 input_image_plus = IJ.openImage(input) | |
| 137 | |
| 138 # Create a copy of the image. | |
| 139 input_image_plus_copy = input_image_plus.duplicate() | |
| 140 image_processor_copy = input_image_plus_copy.getProcessor() | |
| 141 | |
| 142 # Set binary options. | |
| 143 options_list = OPTIONS | |
| 144 if black_background: | |
| 145 options_list.append("black") | |
| 146 options = " ".join(options_list) | |
| 147 IJ.run(input_image_plus_copy, "Options...", options) | |
| 148 | |
| 149 # Convert image to binary if necessary. | |
| 150 if not image_processor_copy.isBinary(): | |
| 151 IJ.run(input_image_plus_copy, "Make Binary", "") | |
| 152 | |
| 153 # Run AnalyzeSkeleton | |
| 154 analyze_skeleton = AnalyzeSkeleton_() | |
| 155 analyze_skeleton.setup("", input_image_plus_copy) | |
| 156 if prune_cycle_method == "none": | |
| 157 prune_index = analyze_skeleton.NONE | |
| 158 elif prune_cycle_method == "shortest_branch": | |
| 159 prune_index = analyze_skeleton.SHORTEST_BRANCH | |
| 160 elif prune_cycle_method == "lowest_intensity_voxel": | |
| 161 prune_index = analyze_skeleton.LOWEST_INTENSITY_VOXEL | |
| 162 elif prune_cycle_method == "lowest_intensity_branch": | |
| 163 prune_index = analyze_skeleton.LOWEST_INTENSITY_BRANCH | |
| 164 result = analyze_skeleton.run( | |
| 165 prune_index, | |
| 166 prune_ends, | |
| 167 calculate_largest_shortest_path, | |
| 168 input_image_plus_copy, | |
| 169 True, | |
| 170 True, | |
| 171 ) | |
| 172 # Save the results. | |
| 173 save(result, output, show_detailed_info, calculate_largest_shortest_path) |
