rimageanalysistools 5.1.2-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+