find_beads 0.9.0-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.
- data/bin/find_beads +33 -0
- data/lib/find_beads/version.rb +33 -0
- data/lib/find_beads.rb +502 -0
- metadata +89 -0
data/bin/find_beads
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# /* ***** BEGIN LICENSE BLOCK *****
|
4
|
+
# *
|
5
|
+
# * Copyright (c) 2013 Colin J. Fuller
|
6
|
+
# *
|
7
|
+
# * Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# * of this software and associated documentation files (the Software), to deal
|
9
|
+
# * in the Software without restriction, including without limitation the rights
|
10
|
+
# * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# * copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# * furnished to do so, subject to the following conditions:
|
13
|
+
# *
|
14
|
+
# * The above copyright notice and this permission notice shall be included in
|
15
|
+
# * all copies or substantial portions of the Software.
|
16
|
+
# *
|
17
|
+
# * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# * SOFTWARE.
|
24
|
+
# *
|
25
|
+
# * ***** END LICENSE BLOCK ***** */
|
26
|
+
#++
|
27
|
+
|
28
|
+
require 'find_beads'
|
29
|
+
|
30
|
+
FindBeads.run_find_beads
|
31
|
+
|
32
|
+
|
33
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#--
|
2
|
+
# /* ***** BEGIN LICENSE BLOCK *****
|
3
|
+
# *
|
4
|
+
# * Copyright (c) 2013 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
|
+
module FindBeads
|
28
|
+
|
29
|
+
VERSION = '0.9.0'
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
data/lib/find_beads.rb
ADDED
@@ -0,0 +1,502 @@
|
|
1
|
+
#--
|
2
|
+
# /* ***** BEGIN LICENSE BLOCK *****
|
3
|
+
# *
|
4
|
+
# * Copyright (c) 2013 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/get_image'
|
29
|
+
require 'rimageanalysistools/image_shortcuts'
|
30
|
+
require 'rimageanalysistools/create_parameters'
|
31
|
+
require 'rimageanalysistools/graythresh'
|
32
|
+
|
33
|
+
require 'edu/stanford/cfuller/imageanalysistools/resources/common_methods'
|
34
|
+
|
35
|
+
require 'trollop'
|
36
|
+
|
37
|
+
##
|
38
|
+
# Functions for segmenting and quantifying beads.
|
39
|
+
#
|
40
|
+
module FindBeads
|
41
|
+
|
42
|
+
include IATScripting
|
43
|
+
|
44
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageCoordinate
|
45
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageSet
|
46
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.meta.parameters.ParameterDictionary
|
47
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.filter.MaximumSeparabilityThresholdingFilter
|
48
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.filter.LabelFilter
|
49
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.filter.SizeAbsoluteFilter
|
50
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.filter.VoronoiFilter
|
51
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.filter.MaskFilter
|
52
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.metric.IntensityPerPixelMetric
|
53
|
+
java_import Java::edu.stanford.cfuller.imageanalysistools.image.Histogram
|
54
|
+
|
55
|
+
DEFAULT_SEG_CH = 2
|
56
|
+
DEFAULT_SEG_PL = 8
|
57
|
+
DEFAULT_BEAD_RADIUS = 24.0
|
58
|
+
|
59
|
+
##
|
60
|
+
# Finds the centroid of each unique-greylevel region in a mask.
|
61
|
+
#
|
62
|
+
# @param [Image] mask the mask in which the regions appear. 0 denotes background and will not be counted.
|
63
|
+
# @return [Hash] a hash where keys are the greylevels of each region in the mask, and the values are
|
64
|
+
# two-element arrays containing the x,y-coordinates of the centroids of these regions.
|
65
|
+
#
|
66
|
+
def self.centroids(mask)
|
67
|
+
|
68
|
+
cens = {}
|
69
|
+
|
70
|
+
mask.each do |ic|
|
71
|
+
|
72
|
+
next unless mask[ic] > 0
|
73
|
+
|
74
|
+
cens[mask[ic]] = [0.0, 0.0] unless cens[mask[ic]]
|
75
|
+
|
76
|
+
cens[mask[ic]][0] += ic[:x]
|
77
|
+
cens[mask[ic]][1] += ic[:y]
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
h = Histogram.new(mask)
|
82
|
+
|
83
|
+
cens.each_key do |k|
|
84
|
+
|
85
|
+
cens[k].map! { |e| e / h.getCounts(k) }
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
cens
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Checks if a given coordinate would be approximately on the boundary between two regions of a
|
95
|
+
# Voronoi diagram of constructed from a set of points. The approximation is calculated such that no
|
96
|
+
# two regions in the Voronoi diagram would be 8-connected.
|
97
|
+
#
|
98
|
+
# @param [Array] points an array of two-element arrays containing the x,y coordinates of the points
|
99
|
+
# on which the diagram is calculated.
|
100
|
+
# @param [ImageCoordinate] ic an ImageCoordinate specifying the location to check.
|
101
|
+
# @return [Boolean] whether the point is on the border between two regions.
|
102
|
+
#
|
103
|
+
def self.is_on_voronoi_border?(points, ic)
|
104
|
+
|
105
|
+
x = ic[:x]
|
106
|
+
y = ic[:y]
|
107
|
+
|
108
|
+
closest_index = 0
|
109
|
+
next_index = 0
|
110
|
+
closest_dist = Float::MAX
|
111
|
+
next_dist = Float::MAX
|
112
|
+
|
113
|
+
|
114
|
+
points.each_with_index do |p, i|
|
115
|
+
|
116
|
+
dist = Math.hypot(p[0] - x, p[1] - y)
|
117
|
+
|
118
|
+
if dist < closest_dist then
|
119
|
+
|
120
|
+
next_dist = closest_dist
|
121
|
+
|
122
|
+
next_index = closest_index
|
123
|
+
|
124
|
+
closest_dist = dist
|
125
|
+
|
126
|
+
closest_index = i
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
cutoff = 2*Math.sqrt(2)
|
133
|
+
|
134
|
+
if next_dist - closest_dist < cutoff then
|
135
|
+
|
136
|
+
true
|
137
|
+
|
138
|
+
else
|
139
|
+
|
140
|
+
false
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Recursively thresholds regions in a supplied mask and image using the method described in
|
148
|
+
# Xiong et al. (DOI: 10.1109/ICIP.2006.312365).
|
149
|
+
#
|
150
|
+
# @param [ParameterDictionary] p a ParameterDictionary specifying max_size and min_size parameters,
|
151
|
+
# which control the maximum size of regions before they are recursively thresholded to break them up,
|
152
|
+
# and the minimum size of regions before they are discarded.
|
153
|
+
# @param [Image] im the original image being segmented. This will not be modified.
|
154
|
+
# @param [Image] mask the initial segmentation mask for the supplied image. Regions in this mask may
|
155
|
+
# be divided up or discarded.
|
156
|
+
# @return [void]
|
157
|
+
#
|
158
|
+
def self.recursive_threshold(p, im, mask)
|
159
|
+
|
160
|
+
h = Histogram.new(mask)
|
161
|
+
|
162
|
+
changed = false
|
163
|
+
|
164
|
+
discard_list = {}
|
165
|
+
|
166
|
+
1.upto(h.getMaxValue) do |i|
|
167
|
+
|
168
|
+
if h.getCounts(i) > p[:max_size].to_i then
|
169
|
+
|
170
|
+
values = []
|
171
|
+
|
172
|
+
im.each do |ic|
|
173
|
+
|
174
|
+
if mask[ic] == i then
|
175
|
+
|
176
|
+
values << im[ic]
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
thresh = RImageAnalysisTools.graythresh(values)
|
183
|
+
|
184
|
+
im.each do |ic|
|
185
|
+
|
186
|
+
if mask[ic] == i and im[ic] <= thresh then
|
187
|
+
|
188
|
+
mask[ic] = 0
|
189
|
+
|
190
|
+
changed = true
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
elsif h.getCounts(i) > 0 and h.getCounts(i) < p[:min_size].to_i then
|
197
|
+
|
198
|
+
discard_list[i] = true
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
im.each do |ic|
|
205
|
+
|
206
|
+
if discard_list[im[ic]] then
|
207
|
+
|
208
|
+
mask[ic] = 0
|
209
|
+
|
210
|
+
changed = true
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
if changed then
|
218
|
+
|
219
|
+
lf = LabelFilter.new
|
220
|
+
|
221
|
+
lf.apply(mask)
|
222
|
+
|
223
|
+
recursive_threshold(p, im, mask)
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
##
|
230
|
+
# Caclulates the maximum allowed size of a bead from the supplied radius.
|
231
|
+
# This is set to be slightly larger than a circle of that radius.
|
232
|
+
#
|
233
|
+
# @param [Fixnum] rad the radius of the bead in units of pixels.
|
234
|
+
#
|
235
|
+
def self.calculate_max_size_from_radius(rad)
|
236
|
+
|
237
|
+
((rad+1)**2 * 3.2).to_i
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
##
|
242
|
+
# Calculates the minimum allowed size of a bead from the supplied radius.
|
243
|
+
# This is set to be slightly smaller than a third of a circle of that radius.
|
244
|
+
# (Note that this is smaller than any of the returned regions should be, but making
|
245
|
+
# the cutoff this small is useful for dividing up clumps of beads where several rounds
|
246
|
+
# or recursive thresholding may make the regions quite small temporarily.)
|
247
|
+
#
|
248
|
+
# @param @see #calculate_max_size_from_radius
|
249
|
+
#
|
250
|
+
def self.calculate_min_size_from_radius(rad)
|
251
|
+
|
252
|
+
(0.96* (rad+1)**2).to_i
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
##
|
257
|
+
# Generates a segmented mask of beads from an image.
|
258
|
+
#
|
259
|
+
# @param [Image] im the image to segment
|
260
|
+
# @param [Hash] opts a hash of commandline arguments.
|
261
|
+
#
|
262
|
+
def self.mask_from_image(im, opts)
|
263
|
+
|
264
|
+
seg_ch = nil
|
265
|
+
seg_pl = nil
|
266
|
+
rad = nil
|
267
|
+
|
268
|
+
if opts then
|
269
|
+
seg_ch = opts[:segchannel]
|
270
|
+
seg_pl = opts[:segplane]
|
271
|
+
rad = opts[:beadradius]
|
272
|
+
else
|
273
|
+
seg_ch = DEFAULT_SEG_CH
|
274
|
+
seg_pl = DEFAULT_SEG_PL
|
275
|
+
rad = DEFAULT_BEAD_RADIUS
|
276
|
+
end
|
277
|
+
|
278
|
+
min_size = calculate_min_size_from_radius(rad)
|
279
|
+
max_size = calculate_max_size_from_radius(rad)
|
280
|
+
|
281
|
+
sizes = ImageCoordinate.cloneCoord(im.getDimensionSizes)
|
282
|
+
|
283
|
+
sizes[:c] = 1
|
284
|
+
sizes[:z] = 1
|
285
|
+
|
286
|
+
im0 = ImageCoordinate.createCoordXYZCT(0,0,0,0,0)
|
287
|
+
|
288
|
+
im0[:c] = seg_ch
|
289
|
+
im0[:z] = seg_pl
|
290
|
+
|
291
|
+
to_seg = im.subImage(sizes, im0).writableInstance
|
292
|
+
|
293
|
+
p = RImageAnalysisTools.create_parameter_dictionary(min_size: min_size, max_size: max_size)
|
294
|
+
|
295
|
+
im_cp = writable_image_copy(to_seg)
|
296
|
+
|
297
|
+
mstf = MaximumSeparabilityThresholdingFilter.new
|
298
|
+
|
299
|
+
lf = LabelFilter.new
|
300
|
+
|
301
|
+
saf = SizeAbsoluteFilter.new
|
302
|
+
|
303
|
+
filters = []
|
304
|
+
|
305
|
+
filters << mstf
|
306
|
+
|
307
|
+
filters << lf
|
308
|
+
|
309
|
+
filters.each do |f|
|
310
|
+
|
311
|
+
f.setParameters(p)
|
312
|
+
f.setReferenceImage(im_cp)
|
313
|
+
f.apply(to_seg)
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
recursive_threshold(p, im_cp, to_seg)
|
318
|
+
|
319
|
+
saf.setParameters(p)
|
320
|
+
|
321
|
+
saf.apply(to_seg)
|
322
|
+
|
323
|
+
cens = centroids(to_seg)
|
324
|
+
|
325
|
+
final_mask = writable_image_copy(to_seg)
|
326
|
+
|
327
|
+
radius = rad
|
328
|
+
|
329
|
+
final_mask.each do |ic|
|
330
|
+
|
331
|
+
final_mask[ic] = 0
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
final_mask.each do |ic|
|
336
|
+
|
337
|
+
x = ic[:x]
|
338
|
+
y = ic[:y]
|
339
|
+
|
340
|
+
cens.each_key do |k|
|
341
|
+
|
342
|
+
if Math.hypot(cens[k][0] - x, cens[k][1] - y) <= radius then
|
343
|
+
|
344
|
+
final_mask[ic] = k
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
end
|
349
|
+
|
350
|
+
end
|
351
|
+
|
352
|
+
|
353
|
+
final_mask.each do |ic|
|
354
|
+
|
355
|
+
next unless final_mask[ic] > 0
|
356
|
+
|
357
|
+
if is_on_voronoi_border?(cens.values, ic) then
|
358
|
+
|
359
|
+
final_mask[ic] = 0
|
360
|
+
|
361
|
+
end
|
362
|
+
|
363
|
+
end
|
364
|
+
|
365
|
+
lf.apply(final_mask)
|
366
|
+
|
367
|
+
saf.apply(final_mask)
|
368
|
+
|
369
|
+
lf.apply(final_mask)
|
370
|
+
|
371
|
+
final_mask
|
372
|
+
|
373
|
+
end
|
374
|
+
|
375
|
+
##
|
376
|
+
# Writes the output data and mask to files.
|
377
|
+
#
|
378
|
+
# @param [String] fn_orig the original filename of the image being segmented/quantified.
|
379
|
+
# @param [String] quant_str the quantification data to write
|
380
|
+
# @param [Image] mask the mask to write
|
381
|
+
#
|
382
|
+
def self.write_output(fn_orig, quant_str, mask)
|
383
|
+
|
384
|
+
mask_dir = "output_mask"
|
385
|
+
|
386
|
+
quant_dir = "quantification"
|
387
|
+
|
388
|
+
mask_ext = "_mask.ome.tif"
|
389
|
+
|
390
|
+
quant_ext = "_quant.txt"
|
391
|
+
|
392
|
+
dir = File.dirname(fn_orig)
|
393
|
+
|
394
|
+
base = File.basename(fn_orig)
|
395
|
+
|
396
|
+
base = base.gsub(".ome.tif", "")
|
397
|
+
|
398
|
+
mask_dir = File.expand_path(mask_dir, dir)
|
399
|
+
|
400
|
+
quant_dir = File.expand_path(quant_dir, dir)
|
401
|
+
|
402
|
+
Dir.mkdir(mask_dir) unless Dir.exist?(mask_dir)
|
403
|
+
Dir.mkdir(quant_dir) unless Dir.exist?(quant_dir)
|
404
|
+
|
405
|
+
mask.writeToFile(File.expand_path(base + mask_ext, mask_dir))
|
406
|
+
|
407
|
+
File.open(File.expand_path(base + quant_ext, quant_dir), 'w') do |f|
|
408
|
+
|
409
|
+
f.puts(quant_str)
|
410
|
+
|
411
|
+
end
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
##
|
416
|
+
# Processes a single file, which consists of creating a mask, quantifying regions, and writing output.
|
417
|
+
#
|
418
|
+
# @param [String] fn the filename of the image to process
|
419
|
+
# @param [Hash] opts a hash of command line options.
|
420
|
+
#
|
421
|
+
def self.process_file(fn, opts=nil)
|
422
|
+
|
423
|
+
puts "processing #{fn}"
|
424
|
+
|
425
|
+
im = RImageAnalysisTools.get_image(fn)
|
426
|
+
|
427
|
+
mask = mask_from_image(im, opts)
|
428
|
+
|
429
|
+
proj = Java::edu.stanford.cfuller.imageanalysistools.frontend.MaximumIntensityProjection.projectImage(im)
|
430
|
+
|
431
|
+
ims = proj.splitChannels
|
432
|
+
|
433
|
+
is = ImageSet.new(ParameterDictionary.emptyDictionary)
|
434
|
+
|
435
|
+
ims.each do |imc|
|
436
|
+
|
437
|
+
is.addImageWithImage(imc)
|
438
|
+
|
439
|
+
end
|
440
|
+
|
441
|
+
met = IntensityPerPixelMetric.new
|
442
|
+
|
443
|
+
q = met.quantify(mask, is)
|
444
|
+
|
445
|
+
outdat = Java::edu.stanford.cfuller.imageanalysistools.frontend.LocalAnalysis.generateDataOutputString(q, nil)
|
446
|
+
|
447
|
+
write_output(fn, outdat, mask)
|
448
|
+
|
449
|
+
end
|
450
|
+
|
451
|
+
##
|
452
|
+
# Runs the bead finding on a file or directory, and grabs options from the command line.
|
453
|
+
#
|
454
|
+
def self.run_find_beads
|
455
|
+
|
456
|
+
opts = Trollop::options do
|
457
|
+
|
458
|
+
opt :dir, "Directory to process", :type => :string
|
459
|
+
opt :file, "File to process", :type => :string
|
460
|
+
opt :segchannel, "Channel on which to segment (0-indexed)", :type => :integer, :default => DEFAULT_SEG_CH
|
461
|
+
opt :segplane, "Plane on which to segment (0-indexed)", :type => :integer, :default => DEFAULT_SEG_PL
|
462
|
+
opt :beadradius, "Radius of the bead in pixels", :type => :float, :default => DEFAULT_BEAD_RADIUS
|
463
|
+
|
464
|
+
end
|
465
|
+
|
466
|
+
if opts[:dir] then
|
467
|
+
|
468
|
+
fod = opts[:dir]
|
469
|
+
|
470
|
+
Dir.foreach(fod) do |f|
|
471
|
+
|
472
|
+
fn = File.expand_path(f, fod)
|
473
|
+
|
474
|
+
if File.file?(fn) then
|
475
|
+
|
476
|
+
begin
|
477
|
+
|
478
|
+
process_file(fn, opts)
|
479
|
+
|
480
|
+
rescue Exception => e
|
481
|
+
|
482
|
+
puts "Unable to process #{fn}:"
|
483
|
+
puts e.message
|
484
|
+
|
485
|
+
end
|
486
|
+
|
487
|
+
end
|
488
|
+
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
if opts[:file] then
|
494
|
+
|
495
|
+
process_file(opts[:file], opts)
|
496
|
+
|
497
|
+
end
|
498
|
+
|
499
|
+
end
|
500
|
+
|
501
|
+
end
|
502
|
+
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: find_beads
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
prerelease:
|
6
|
+
platform: java
|
7
|
+
authors:
|
8
|
+
- Colin J. Fuller
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rimageanalysistools
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: !binary |-
|
21
|
+
MA==
|
22
|
+
none: false
|
23
|
+
requirement: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: !binary |-
|
28
|
+
MA==
|
29
|
+
none: false
|
30
|
+
prerelease: false
|
31
|
+
type: :runtime
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: trollop
|
34
|
+
version_requirements: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: !binary |-
|
39
|
+
MA==
|
40
|
+
none: false
|
41
|
+
requirement: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: !binary |-
|
46
|
+
MA==
|
47
|
+
none: false
|
48
|
+
prerelease: false
|
49
|
+
type: :runtime
|
50
|
+
description: Segments and quantifies beads in microscopy images
|
51
|
+
email: cjfuller@gmail.com
|
52
|
+
executables:
|
53
|
+
- find_beads
|
54
|
+
extensions: []
|
55
|
+
extra_rdoc_files: []
|
56
|
+
files:
|
57
|
+
- lib/find_beads.rb
|
58
|
+
- lib/find_beads/version.rb
|
59
|
+
- bin/find_beads
|
60
|
+
homepage: http://github.com/cjfuller/find_beads
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: !binary |-
|
72
|
+
MA==
|
73
|
+
none: false
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: !binary |-
|
79
|
+
MA==
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- jruby
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.8.24
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Segments and quantifies beads in microscopy images
|
88
|
+
test_files: []
|
89
|
+
has_rdoc:
|