panelize 1.0.0-java → 1.1.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.
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