rimageanalysistools 5.1.2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,38 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2012 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+
28
+ module RImageAnalysisTools
29
+
30
+ class Method
31
+
32
+ attr_accessor :parameters, :metadata, :input_images, :output_images, :quantification
33
+
34
+ end
35
+
36
+
37
+ end
38
+
@@ -0,0 +1,74 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2012 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ require 'rimageanalysistools/initjava'
28
+
29
+ java_import Java::edu.stanford.cfuller.imageanalysistools.frontend.LocalAnalysis
30
+
31
+ module RImageAnalysisTools
32
+
33
+ IM_OUTPUT_DIR = "output_images"
34
+ QUANT_OUTPUT_DIR = "quantification"
35
+
36
+ def self.handle_output(original_filename, output_image, quant)
37
+
38
+ fn_parts = File.split(original_filename)
39
+
40
+ im_dir = File.expand_path(IM_OUTPUT_DIR, fn_parts[0])
41
+
42
+ quant_dir = File.expand_path(QUANT_OUTPUT_DIR, fn_parts[0])
43
+
44
+ Dir.mkdir(im_dir) unless Dir.exist?(im_dir)
45
+ Dir.mkdir(quant_dir) unless Dir.exist?(quant_dir)
46
+
47
+ mask_fn = fn_parts[1] + "_output.ome.tif"
48
+
49
+ quant_fn = fn_parts[1] + "_quant.txt"
50
+
51
+ unless quant.nil? then
52
+
53
+ quant_str = LocalAnalysis.generateDataOutputString(quant, nil)
54
+
55
+ File.open(File.expand_path(quant_fn, quant_dir), 'w') do |f|
56
+ f.puts quant_str
57
+ end
58
+
59
+ end
60
+
61
+ unless output_image.nil? then
62
+
63
+ output_image.writeToFile(File.expand_path(mask_fn, im_dir))
64
+
65
+ end
66
+
67
+ end
68
+
69
+
70
+
71
+ end
72
+
73
+
74
+
@@ -0,0 +1,250 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2012 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ require 'rimageanalysistools'
28
+ require 'rimageanalysistools/image_shortcuts'
29
+
30
+ java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageCoordinate
31
+
32
+ module RImageAnalysisTools
33
+
34
+ class Skeletonizer
35
+
36
+ #implementation of skeletonization algorithm presented in Gonzalez & Woods, p 651-652
37
+
38
+ def initialize(im)
39
+
40
+ @im = im
41
+
42
+ end
43
+
44
+ def compute_n(ic)
45
+
46
+ temp_ic = ImageCoordinate.cloneCoord(ic)
47
+
48
+ n = -1 # compensate for 0,0 case
49
+
50
+ x_off = [-1,0,1]
51
+ y_off = [-1,0,1]
52
+
53
+ x_off.each do |x|
54
+ y_off.each do |y|
55
+
56
+ temp_ic[:x] = ic[:x] + x
57
+ temp_ic[:y] = ic[:y] + y
58
+
59
+ if @im.inBounds(temp_ic) and @im[temp_ic] == @im[ic] then
60
+ n += 1
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ temp_ic.recycle
68
+
69
+ n
70
+
71
+ end
72
+
73
+ def compute_t(ic)
74
+
75
+ temp_ic1 = ImageCoordinate.cloneCoord(ic)
76
+ temp_ic2 = ImageCoordinate.cloneCoord(ic)
77
+
78
+ pixel_offsets = [[0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1]]
79
+
80
+ t = 0
81
+
82
+ 0.upto(pixel_offsets.length - 2) do |i|
83
+
84
+ p1 = pixel_offsets[i]
85
+ p2 = pixel_offsets[i+1]
86
+
87
+ temp_ic1[:x] = ic[:x] + p1[0]
88
+ temp_ic2[:x] = ic[:x] + p2[0]
89
+
90
+ temp_ic1[:y] = ic[:y] + p1[1]
91
+ temp_ic2[:y] = ic[:y] + p2[1]
92
+
93
+ v1 = 0
94
+ v2 = 0
95
+
96
+ v1 = 1 if @im.inBounds(temp_ic1) and @im[ic] == @im[temp_ic1]
97
+ v2 = 1 if @im.inBounds(temp_ic2) and @im[ic] == @im[temp_ic2]
98
+
99
+ t += 1 if v2 - v1 == 1
100
+
101
+ end
102
+
103
+ temp_ic1.recycle
104
+ temp_ic2.recycle
105
+
106
+ t
107
+
108
+ end
109
+
110
+ def compute_pixel_product(ic, pixel_offsets)
111
+
112
+ temp_ic = ImageCoordinate.cloneCoord(ic)
113
+
114
+ pixel_offsets.each do |po|
115
+
116
+ temp_ic[:x]= ic[:x] + po[0]
117
+ temp_ic[:y]= ic[:y] + po[1]
118
+
119
+ unless @im.inBounds(temp_ic) and @im[temp_ic] == @im[ic] then
120
+ temp_ic.recycle
121
+ return 0
122
+ end
123
+
124
+ end
125
+
126
+ temp_ic.recycle
127
+
128
+ 1
129
+
130
+ end
131
+
132
+ def pass1(ic)
133
+
134
+ n = compute_n(ic)
135
+
136
+ return false if n < 2 or n > 6
137
+
138
+ t = compute_t(ic)
139
+
140
+ return false unless t == 1
141
+
142
+ pixels246 = [[0, -1], [1, 0], [0, 1]]
143
+
144
+ p246 = compute_pixel_product(ic, pixels246)
145
+
146
+ return false unless p246 == 0
147
+
148
+ pixels468 = [[1, 0], [0, 1], [-1, 0]]
149
+
150
+ p468 = compute_pixel_product(ic, pixels468)
151
+
152
+ return false unless p468 == 0
153
+
154
+ true
155
+
156
+ end
157
+
158
+ def pass2(ic)
159
+
160
+ n = compute_n(ic)
161
+
162
+ return false if n < 2 or n > 6
163
+
164
+ t = compute_t(ic)
165
+
166
+ return false unless t == 1
167
+
168
+ pixels248 = [[0, -1], [1, 0], [-1, 0]]
169
+
170
+ p248 = compute_pixel_product(ic, pixels248)
171
+
172
+ return false unless p248 == 0
173
+
174
+ pixels268 = [[0, -1], [0, 1], [-1, 0]]
175
+
176
+ p268 = compute_pixel_product(ic, pixels268)
177
+
178
+ return false unless p268 == 0
179
+
180
+ true
181
+
182
+ end
183
+
184
+ def do_iteration
185
+
186
+ flagged1 = []
187
+
188
+ @im.each do |ic|
189
+
190
+ next if @im[ic] == 0
191
+
192
+ should_flag = pass1(ic)
193
+
194
+ if should_flag then
195
+ flagged1 << ImageCoordinate.cloneCoord(ic)
196
+ end
197
+
198
+ end
199
+
200
+ flagged1.each do |ic|
201
+
202
+ @im[ic]= 0
203
+
204
+ ic.recycle
205
+
206
+ end
207
+
208
+ flagged2 = []
209
+
210
+ @im.each do |ic|
211
+
212
+ next if @im[ic] == 0
213
+
214
+ should_flag = pass2(ic)
215
+
216
+ if should_flag then
217
+
218
+ flagged2 << ImageCoordinate.cloneCoord(ic)
219
+
220
+ end
221
+
222
+ end
223
+
224
+ flagged2.each do |ic|
225
+
226
+ @im[ic]= 0
227
+
228
+ ic.recycle
229
+
230
+ end
231
+
232
+ changed = (not (flagged1.empty? and flagged2.empty?))
233
+
234
+ changed
235
+
236
+ end
237
+
238
+ def skeletonize
239
+
240
+ while do_iteration do
241
+
242
+ end
243
+
244
+ end
245
+
246
+
247
+ end
248
+
249
+ end
250
+
@@ -0,0 +1,140 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2012 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+
28
+ module RImageAnalysisTools
29
+
30
+ class ThreadQueue
31
+
32
+ def self.new_scope_with_vars(*args)
33
+
34
+ yield *args
35
+
36
+ end
37
+
38
+ def initialize
39
+ @threads = Array.new
40
+ @waiting = Array.new
41
+ @mut = Mutex.new
42
+ @max_threads = 4
43
+ @running = false
44
+ @results = []
45
+ end
46
+
47
+ attr_reader :running
48
+
49
+ def enqueue(&b)
50
+
51
+ @mut.synchronize do
52
+ @waiting << b
53
+ end
54
+
55
+ end
56
+
57
+ def start_queue
58
+
59
+ return nil if @running
60
+
61
+ @running = true
62
+
63
+ Thread.new do
64
+
65
+ until empty? do
66
+
67
+ run_thread_if_space
68
+
69
+ sleep 0.2
70
+
71
+ end
72
+
73
+ @running = false
74
+
75
+ end
76
+
77
+ end
78
+
79
+ def run_thread_if_space
80
+
81
+ @mut.synchronize do
82
+ while (not @threads.size >= @max_threads) and (not @waiting.empty?) do
83
+ next_task = @waiting.pop
84
+ @threads << Thread.new(next_task) do |task|
85
+ task.call
86
+ end
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ def remove_completed_threads
93
+
94
+ dead = Array.new
95
+
96
+ @threads.each do |t|
97
+ if not t.alive? then
98
+ dead << t
99
+ end
100
+ end
101
+
102
+ @mut.synchronize do
103
+ dead.each do |d|
104
+ @results << d.value
105
+ @threads.delete(d)
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ def finish
112
+ until empty? do
113
+ remove_completed_threads
114
+ sleep 0.5
115
+ end
116
+ @results
117
+ end
118
+
119
+
120
+
121
+ attr_accessor :max_threads
122
+
123
+ def has_running_threads?
124
+ remove_completed_threads
125
+ not @threads.empty?
126
+ end
127
+
128
+
129
+ def empty?
130
+ @mut.synchronize do
131
+ @threads.empty? and @waiting.empty?
132
+ end
133
+ end
134
+
135
+ end
136
+
137
+ end
138
+
139
+
140
+