Mercurial > repos > bgruening > imagej2_crop
comparison imagej2_analyze_skeleton_jython_script.py @ 0:018144807556 draft default tip
planemo upload for repository https://github.com/bgruening/galaxytools/tree/master/tools/image_processing/imagej2 commit 8f49f3c66b5a1de99ec15e65c2519a56792f1d56
author | bgruening |
---|---|
date | Tue, 24 Sep 2024 17:12:52 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:018144807556 |
---|---|
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) |