panelize 1.0.0-java → 1.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/panelize.rb +212 -205
  2. data/lib/panelize/version.rb +1 -1
  3. metadata +2 -2
data/lib/panelize.rb CHANGED
@@ -29,210 +29,217 @@ require 'highline/import'
29
29
 
30
30
  module Panelize
31
31
 
32
- java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageCoordinate
33
- java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageFactory
34
- java_import Java::edu.stanford.cfuller.imageanalysistools.image.Histogram
35
- java_import Java::ij.process.ColorProcessor
36
- java_import Java::ij.ImagePlus
37
- java_import Java::ij.io.FileSaver
38
-
39
- class << self
40
-
41
- def box_channel(im, ch)
42
- lower = ImageCoordinate[0,0,0,0,0]
43
- upper = ImageCoordinate.cloneCoord(im.getDimensionSizes)
44
- lower[:c] = ch
45
- upper[:c] = ch+1
46
- im.setBoxOfInterest(lower, upper)
47
- lower.recycle
48
- upper.recycle
49
- nil
50
- end
51
-
52
- def display(im, params)
53
- box_channel(im, params[:col_chs][0])
54
- max = Histogram.findMaxVal(im)
55
- im.clearBoxOfInterest
56
- imp = im.toImagePlus
57
- imp.setOpenAsHyperStack true
58
- imp.updatePosition(params[:col_chs][0]+1, 1, 1)
59
- imp.setDisplayRange(0, max)
60
- imp.setRoi 0,0, params[:size], params[:size]
61
- imp.show
62
- ask("Move the region of interest to where you want to crop and press enter when done.")
63
- ul = [imp.getRoi.getPolygon.xpoints[0], imp.getRoi.getPolygon.ypoints[0]]
64
- end
65
-
66
- def crop(im, ul, params)
67
- sizes = ImageCoordinate.cloneCoord(im.getDimensionSizes)
68
- sizes[:x] = params[:size]
69
- sizes[:y] = params[:size]
70
- ul_coord = ImageCoordinate[ul[0], ul[1], 0,0,0]
71
- im_crop = im.subImage(sizes, ul_coord)
72
- im.toImagePlus.close
73
- sizes.recycle
74
- ul_coord.recycle
75
- im_crop
76
- end
77
-
78
- def load_and_crop(fn, params)
79
- im = RImageAnalysisTools.get_image(fn)
80
- ul = display(im, params)
81
- crop(im, ul, params)
82
- end
83
-
84
- def calculate_channel_scale(ims, params)
85
- scale = {}
86
-
87
- params[:col_chs].each do |ch|
88
- min = Float::MAX
89
- max = -1.0*Float::MAX
90
-
91
- ims.each do |im|
92
- box_channel(im, ch)
93
-
94
- h = Histogram.new(im)
95
- min = h.getMinValue if h.getMinValue < min
96
- max = h.getMaxValue if h.getMaxValue > max
97
- end
98
-
99
- scale[ch] = [min + params[:scaleundersat]/100*(max-min), max - params[:scalesat]/100*(max-min)]
100
- end
101
-
102
- scale
103
- end
104
-
105
- def scale_to_8_bit(value, scale)
106
- value = 255*(value - scale[0])/(scale[1]-scale[0])
107
- value = 0 if value < 0
108
- value = 255 if value > 255
109
- value
110
- end
111
-
112
- def add_scalebar(panel_image, params)
113
- scalebar_length_px = params[:scalebar]/params[:mpp]
114
-
115
- y_start = calculate_height(params) - 2*params[:spacing]
116
- x_start = params[:spacing]
117
-
118
- x_start.upto(x_start + scalebar_length_px - 1) do |x|
119
- y_start.upto(y_start + params[:spacing] - 1) do |y|
120
- panel_image.putPixel(x, y, [255, 255, 255].to_java(:int))
121
- end
122
- end
123
- end
124
-
125
-
126
- def place_panel(panel_image, start_coord, image, channel, rgb_chs, scales)
127
- box_channel(image, channel)
128
-
129
- rgb_mult = [0, 0, 0]
130
- rgb_mult[0] = 1 if rgb_chs.include? :r
131
- rgb_mult[1] = 1 if rgb_chs.include? :g
132
- rgb_mult[2] = 1 if rgb_chs.include? :b
133
-
134
- image.each do |ic|
135
- v = scale_to_8_bit(image[ic], scales[ic[:c]])
136
- curr_val = panel_image.getPixel(ic[:x] + start_coord[:x], ic[:y] + start_coord[:y], nil)
137
- panel_image.putPixel(ic[:x] + start_coord[:x], ic[:y] + start_coord[:y], rgb_mult.map.with_index { |e, i| e*v + (1-e)*curr_val[i]}.to_java(:int))
138
- end
139
-
140
- nil
141
- end
142
-
143
- def calculate_width(params)
144
- (params[:col_chs].size + 1)*params[:size] + params[:col_chs].size*params[:spacing]
145
- end
146
-
147
- def calculate_height(params)
148
- (params[:n_rows])*params[:size] + (params[:n_rows]-1)*params[:spacing]
149
- end
150
-
151
- def calculate_row_pos(n, params)
152
- n*params[:size] + n*params[:spacing]
153
- end
154
-
155
- def calculate_col_pos(n, params)
156
- n*params[:size] + n*params[:spacing]
157
- end
158
-
159
- def initialize_panel(params)
160
- w = calculate_width(params)
161
- h = calculate_height(params)
162
-
163
- im = ColorProcessor.new(w, h)
164
- w.times do |x|
165
- h.times do |y|
166
- im.putPixel(x, y, [255, 255, 255].to_java(:int))
167
- end
168
- end
169
-
170
- im
171
- end
172
-
173
-
174
- def make_panels(ims, scale, params)
175
- panels = initialize_panel(params)
176
-
177
- params[:n_rows].times do |row|
178
- params[:col_chs].size.times do |col|
179
- place_panel(panels, {y: calculate_row_pos(row, params), x: calculate_col_pos(col, params)}, ims[row], params[:col_chs][col], [:r, :g, :b], scale)
180
- end
181
-
182
- zero_im = ImageFactory.createWritable(ims[0])
183
- zero_im.each { |ic| zero_im[ic] = 0.0 }
184
-
185
- [:r, :g, :b].each_with_index do |ch, i|
186
- if params[:col_chs].size > i then
187
- place_panel(panels, {y:calculate_row_pos(row, params), x: calculate_col_pos(params[:col_chs].size, params)}, ims[row], params[:col_chs][i], [ch], scale)
188
- else
189
- place_panel(panels, {y:calculate_row_pos(row, params), x: calculate_col_pos(params[:col_chs].size, params)}, zero_im, params[:col_chs][0], [ch], scale)
190
- end
191
- end
192
- end
193
-
194
- panels
195
- end
196
-
197
- def save_image(panels)
198
- fs = FileSaver.new(ImagePlus.new("panels", panels))
199
- fn = "panels_#{Time.now.to_i}.tif"
200
- fs.saveAsTiff(fn)
201
- puts "Panels saved as #{fn}"
202
- end
203
-
204
- def ask_for_params(params)
205
- params[:n_rows] = ask("Enter the number of treatments (rows) to panelize: ", Integer)
206
- params[:col_chs] = ask("Enter the channel numbers to display (comma-separated): ", lambda { |str| str.split(/,\s*/).map(&:to_i) })
207
- params[:fns] = []
208
- params[:n_rows].times do |i|
209
- params[:fns] << ask("Enter the filename for treatment #{i+1}: ").gsub("'", "") #remove quotes if drag and drop fn insertion in the terminal puts them in
210
- end
211
- params[:mpp] = ask("Enter the number of microns per pixel (for calculating the length of a scalebar): ", Float)
212
-
213
- end
214
-
215
- def go
216
- params = Trollop::options do
217
- opt :spacing, "Spacing between image panels in pixels", type: :integer, default: 5
218
- opt :size, "Size of the image in pixels", type: :integer, default: 256
219
- opt :scalebar, "Size of the scalebar in microns", type: :float, default: 5.0
220
- opt :scalesat, "Amount in percent by which to saturate images", type: :float, default: 15.0
221
- opt :scaleundersat, "Amount in percent by which to undersaturate images", type: :float, default: 5.0
222
- end
223
-
224
- ask_for_params(params)
225
-
226
- ims = []
227
- params[:fns].each do |fn|
228
- ims << load_and_crop(fn, params)
229
- end
230
-
231
- scale = calculate_channel_scale(ims, params)
232
- panels = make_panels(ims, scale, params)
233
- add_scalebar(panels, params)
234
- save_image(panels)
235
- end
236
- end
32
+ java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageCoordinate
33
+ java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageFactory
34
+ java_import Java::edu.stanford.cfuller.imageanalysistools.image.Histogram
35
+ java_import Java::ij.process.ColorProcessor
36
+ java_import Java::ij.ImagePlus
37
+ java_import Java::ij.io.FileSaver
38
+
39
+ class << self
40
+
41
+ def box_channel(im, ch)
42
+ lower = ImageCoordinate[0,0,0,0,0]
43
+ upper = ImageCoordinate.cloneCoord(im.getDimensionSizes)
44
+ lower[:c] = ch
45
+ upper[:c] = ch+1
46
+ im.setBoxOfInterest(lower, upper)
47
+ lower.recycle
48
+ upper.recycle
49
+ nil
50
+ end
51
+
52
+ def display(im, params)
53
+ box_channel(im, params[:col_chs][0])
54
+ max = Histogram.findMaxVal(im)
55
+ im.clearBoxOfInterest
56
+ imp = im.toImagePlus
57
+ imp.setOpenAsHyperStack true
58
+ imp.updatePosition(params[:col_chs][0]+1, 1, 1)
59
+ imp.setDisplayRange(0, max)
60
+ imp.setRoi 0,0, params[:size], params[:size]
61
+ imp.show
62
+ ask("Move the region of interest to where you want to crop and press enter when done.")
63
+ ul = [imp.getRoi.getPolygon.xpoints[0], imp.getRoi.getPolygon.ypoints[0]]
64
+ end
65
+
66
+ def crop(im, ul, params)
67
+ sizes = ImageCoordinate.cloneCoord(im.getDimensionSizes)
68
+ sizes[:x] = params[:size]
69
+ sizes[:y] = params[:size]
70
+ ul_coord = ImageCoordinate[ul[0], ul[1], 0,0,0]
71
+ im_crop = im.subImage(sizes, ul_coord)
72
+ im.toImagePlus.close
73
+ sizes.recycle
74
+ ul_coord.recycle
75
+ im_crop
76
+ end
77
+
78
+ def load_and_crop(fn, params)
79
+ im = RImageAnalysisTools.get_image(fn)
80
+ ul = display(im, params)
81
+ crop(im, ul, params)
82
+ end
83
+
84
+ def calculate_channel_scale(ims, params)
85
+ scale = {}
86
+
87
+ params[:col_chs].each do |ch|
88
+ min = Float::MAX
89
+ max = -1.0*Float::MAX
90
+
91
+ ims.each do |im|
92
+ box_channel(im, ch)
93
+
94
+ h = Histogram.new(im)
95
+ min = h.getMinValue if h.getMinValue < min
96
+ max = h.getMaxValue if h.getMaxValue > max
97
+ end
98
+
99
+ scale[ch] = [min + params[:scaleundersat]/100*(max-min), max - params[:scalesat]/100*(max-min)]
100
+ end
101
+
102
+ scale
103
+ end
104
+
105
+ def scale_to_8_bit(value, scale)
106
+ value = 255*(value - scale[0])/(scale[1]-scale[0])
107
+ value = 0 if value < 0
108
+ value = 255 if value > 255
109
+ value
110
+ end
111
+
112
+ def add_scalebar(panel_image, params)
113
+ scalebar_length_px = params[:scalebar]/params[:mpp]
114
+
115
+ y_start = calculate_height(params) - 2*params[:spacing]
116
+ x_start = params[:spacing]
117
+
118
+ x_start.upto(x_start + scalebar_length_px - 1) do |x|
119
+ y_start.upto(y_start + params[:spacing] - 1) do |y|
120
+ panel_image.putPixel(x, y, [255, 255, 255].to_java(:int))
121
+ end
122
+ end
123
+ end
124
+
125
+
126
+ def place_panel(panel_image, start_coord, image, channel, rgb_chs, scales)
127
+ box_channel(image, channel)
128
+
129
+ rgb_mult = [0, 0, 0]
130
+ rgb_mult[0] = 1 if rgb_chs.include? :r
131
+ rgb_mult[1] = 1 if rgb_chs.include? :g
132
+ rgb_mult[2] = 1 if rgb_chs.include? :b
133
+
134
+ image.each do |ic|
135
+ v = scale_to_8_bit(image[ic], scales[ic[:c]])
136
+ curr_val = panel_image.getPixel(ic[:x] + start_coord[:x], ic[:y] + start_coord[:y], nil)
137
+ panel_image.putPixel(ic[:x] + start_coord[:x], ic[:y] + start_coord[:y], rgb_mult.map.with_index { |e, i| e*v + (1-e)*curr_val[i]}.to_java(:int))
138
+ end
139
+
140
+ nil
141
+ end
142
+
143
+ def calculate_width(params)
144
+ (params[:col_chs].size + 1)*params[:size] + params[:col_chs].size*params[:spacing]
145
+ end
146
+
147
+ def calculate_height(params)
148
+ (params[:n_rows])*params[:size] + (params[:n_rows]-1)*params[:spacing]
149
+ end
150
+
151
+ def calculate_row_pos(n, params)
152
+ n*params[:size] + n*params[:spacing]
153
+ end
154
+
155
+ def calculate_col_pos(n, params)
156
+ n*params[:size] + n*params[:spacing]
157
+ end
158
+
159
+ def initialize_panel(params)
160
+ w = calculate_width(params)
161
+ h = calculate_height(params)
162
+
163
+ im = ColorProcessor.new(w, h)
164
+ w.times do |x|
165
+ h.times do |y|
166
+ im.putPixel(x, y, [255, 255, 255].to_java(:int))
167
+ end
168
+ end
169
+
170
+ im
171
+ end
172
+
173
+
174
+ def make_panels(ims, scale, params)
175
+ panels = initialize_panel(params)
176
+
177
+ params[:n_rows].times do |row|
178
+ params[:col_chs].size.times do |col|
179
+ place_panel(panels, {y: calculate_row_pos(row, params), x: calculate_col_pos(col, params)}, ims[row], params[:col_chs][col], [:r, :g, :b], scale)
180
+ end
181
+
182
+ zero_im = ImageFactory.createWritable(ims[0])
183
+ zero_im.each { |ic| zero_im[ic] = 0.0 }
184
+
185
+ #zero out merge first in case not all channels are being used
186
+ [:r, :g, :b].each do |ch, i|
187
+ next if params[:col_chs].include? ch
188
+ place_panel(panels, {y:calculate_row_pos(row, params), x: calculate_col_pos(params[:col_chs].size, params)}, zero_im, params[:col_chs][0], [ch], scale)
189
+ end
190
+
191
+ params[:col_order].each_with_index do |ch, i|
192
+ if params[:col_chs].size > i then
193
+ place_panel(panels, {y:calculate_row_pos(row, params), x: calculate_col_pos(params[:col_chs].size, params)}, ims[row], params[:col_chs][i], [ch], scale)
194
+ else
195
+ place_panel(panels, {y:calculate_row_pos(row, params), x: calculate_col_pos(params[:col_chs].size, params)}, zero_im, params[:col_chs][0], [ch], scale)
196
+ end
197
+ end
198
+ end
199
+
200
+ panels
201
+ end
202
+
203
+ def save_image(panels)
204
+ fs = FileSaver.new(ImagePlus.new("panels", panels))
205
+ fn = "panels_#{Time.now.to_i}.tif"
206
+ fs.saveAsTiff(fn)
207
+ puts "Panels saved as #{fn}"
208
+ end
209
+
210
+ def ask_for_params(params)
211
+ params[:n_rows] = ask("Enter the number of treatments (rows) to panelize: ", Integer)
212
+ params[:col_chs] = ask("Enter the channel numbers to display (comma-separated): ", lambda { |str| str.split(/,\s*/).map(&:to_i) })
213
+ params[:col_order] = ask ("Enter the channel order (comma-separated) (default r,g,b if no order given): "), lambda { |str| str.empty? ? [:r, :g, :b] : str.split(/,\s*/).map(&:to_sym) }
214
+ params[:fns] = []
215
+ params[:n_rows].times do |i|
216
+ params[:fns] << ask("Enter the filename for treatment #{i+1}: ").gsub("'", "") #remove quotes if drag and drop fn insertion in the terminal puts them in
217
+ end
218
+ params[:mpp] = ask("Enter the number of microns per pixel (for calculating the length of a scalebar): ", Float)
219
+
220
+ end
221
+
222
+ def go
223
+ params = Trollop::options do
224
+ opt :spacing, "Spacing between image panels in pixels", type: :integer, default: 5
225
+ opt :size, "Size of the image in pixels", type: :integer, default: 256
226
+ opt :scalebar, "Size of the scalebar in microns", type: :float, default: 5.0
227
+ opt :scalesat, "Amount in percent by which to saturate images", type: :float, default: 15.0
228
+ opt :scaleundersat, "Amount in percent by which to undersaturate images", type: :float, default: 5.0
229
+ end
230
+
231
+ ask_for_params(params)
232
+
233
+ ims = []
234
+ params[:fns].each do |fn|
235
+ ims << load_and_crop(fn, params)
236
+ end
237
+
238
+ scale = calculate_channel_scale(ims, params)
239
+ panels = make_panels(ims, scale, params)
240
+ add_scalebar(panels, params)
241
+ save_image(panels)
242
+ end
243
+ end
237
244
  end
238
245
 
@@ -1,3 +1,3 @@
1
1
  module Panelize
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panelize
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: java
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-13 00:00:00.000000000 Z
12
+ date: 2013-05-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rimageanalysistools