panomosity 0.1.21 → 0.1.22

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d3f10415e998af6222a66b2fd33fa287467685da033820bf08549319dd233b3
4
- data.tar.gz: 215dc04025125205c275d224b0d2710f2a1135d11cadbc0b40c42c61e093cb33
3
+ metadata.gz: bb087d6bb2baa65028d713d9dbe1a6137346533b039d163c88106a4c8f47ee92
4
+ data.tar.gz: 7bcb4253e575daf5bd2398d4bdc637fc09ee7a1f3cada8cf70094d3a0db8a180
5
5
  SHA512:
6
- metadata.gz: f54e1297b2745fe8704df22c6cde677bfa19ec7d74554fe45ab05d00fbd6d5d88fc82d7b2bfcd99d57f640cef3d1226fa1068a4f1ee135f9462957c4903ab33f
7
- data.tar.gz: ef4d5656bbd5a7d0747d68dde9ec8c4eaa3877a1c95a7032126b4f0b92d27f82c95c09dc040d9998556fa9f5dc5d345008a887ac1d312e0aa6ca5f67547f8e4f
6
+ metadata.gz: fae56434b44675d564715e477cd4416ff14495a4f80cad77a1c8ab7d029540c239bc14872d327dd4548967708737003c16b5f28061e92faa766c0fdb20c16b14
7
+ data.tar.gz: 1eafe48252190699713109523ab0def1b2ffbdf90aa35f9b9ce22e0a7a83a28f7de40c59bdf9a0f8f13b7bb3c4693ac9abd55dd64800dfb41300a3084ed2e96b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- panomosity (0.1.20)
4
+ panomosity (0.1.21)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/lib/panomosity.rb CHANGED
@@ -58,8 +58,8 @@ module Panomosity
58
58
  options[:verbose] = v
59
59
  end
60
60
 
61
- parser.on('-vv', '--vverbose', 'Run very verbosely') do |v|
62
- options[:very_verbose] = v
61
+ parser.on('--verbosity LEVEL', Integer, 'Set verbosity level') do |v|
62
+ options[:verbosity] = v
63
63
  end
64
64
 
65
65
  parser.on('-h', '--help', 'Display this screen') do
@@ -70,6 +70,8 @@ module Panomosity
70
70
  parser.parse!(arguments)
71
71
  end
72
72
 
73
+ # default options
74
+ options[:verbosity] ||= 0
73
75
  runner = Runner.new(options)
74
76
  runner.run(ARGV[0])
75
77
  end
@@ -84,7 +84,7 @@ module Panomosity
84
84
  logger.debug "#{ng.prdist_avg} #{ng.prdist_std} #{ng.control_points.count} x#{ng.x_avg} y#{ng.y_avg}"
85
85
  end
86
86
 
87
- self.neighborhood_groups = neighborhood_groups.max_by(5) { |ng| ng.control_points.count }
87
+ self.neighborhood_groups = neighborhood_groups.sort_by { |ng| -ng.control_points.count }
88
88
  end
89
89
 
90
90
  def self.info
@@ -113,8 +113,8 @@ module Panomosity
113
113
  def calculate_average_distance
114
114
  Pair.calculate_neighborhoods(panorama)
115
115
  Pair.calculate_neighborhood_groups
116
- horizontal_distances = NeighborhoodGroup.horizontal.map(&:prdist_avg)
117
- vertical_distances = NeighborhoodGroup.vertical.map(&:prdist_avg)
116
+ horizontal_distances = NeighborhoodGroup.horizontal[0..4].map(&:prdist_avg)
117
+ vertical_distances = NeighborhoodGroup.vertical[0..4].map(&:prdist_avg)
118
118
  calculate_average(values: horizontal_distances + vertical_distances)
119
119
  end
120
120
 
@@ -90,7 +90,7 @@ module Panomosity
90
90
  end
91
91
 
92
92
  def self.log_detailed_neighborhood_info(name: :horizontal, pairs: [])
93
- return unless @panorama.options[:very_verbose]
93
+ return unless @panorama.options[:verbosity] > 1
94
94
  logger.debug "showing #{name} pair information"
95
95
  pair = pairs.max_by { |p| p.control_points_of_best_neighborhood.count }
96
96
  logger.debug "best #{name} pair #{pair.to_s} found #{pair.control_points_of_best_neighborhood.count} control points"
@@ -7,6 +7,7 @@ module Panomosity
7
7
  def initialize(input, options = {})
8
8
  @input = input
9
9
  @options = options
10
+ @options[:verbosity] ||= 0
10
11
  @images = Image.parse(@input)
11
12
  @variable = PanoramaVariable.parse(@input).first
12
13
  ControlPoint.parse(@input)
@@ -140,5 +141,107 @@ module Panomosity
140
141
  Pair.info
141
142
  NeighborhoodGroup.info
142
143
  end
144
+
145
+ def diagnose
146
+ Pair.calculate_neighborhoods(self)
147
+ Pair.calculate_neighborhood_groups
148
+
149
+ recommendations = []
150
+
151
+ logger.debug "total number of control points: #{control_points.count}"
152
+ logger.debug "total number of generated control points: #{control_points.select(&:generated?).count}"
153
+ logger.debug "total number of not generated control points: #{control_points.select(&:not_generated?).count}"
154
+
155
+ control_point_pair_ratio = Pair.without_enough_control_points(ignore_connected: true).count.to_f / Pair.all.count
156
+ logger.warn "More than 50% (#{(control_point_pair_ratio*100).round(4)}%) of pairs have fewer than 3 control points. May potentially cause issues." if control_point_pair_ratio >= 0.5
157
+
158
+ control_point_generated_ratio = control_points.select(&:generated?).count.to_f / control_points.select(&:not_generated?).count
159
+ if control_point_generated_ratio >= 0.3
160
+ message = <<~MESSAGE
161
+ More than 30% (#{(control_point_generated_ratio*100).round(4)}%) control points were generated.
162
+ This indicates a failure to find control points between images pairs due to poor lighting or insufficient complexity.
163
+ MESSAGE
164
+ logger.warn message
165
+ end
166
+
167
+ # neighborhood group tests
168
+ group_count = NeighborhoodGroup.horizontal.count
169
+ if group_count < 5
170
+ message = <<~MESSAGE
171
+ Total number of horizontal neighborhood groups is #{group_count} which is very low.
172
+ This can mean either low variation in control points distances or that not enough control points could be found.
173
+ MESSAGE
174
+ logger.warn message
175
+ end
176
+
177
+ group_std_avg = calculate_average(values: NeighborhoodGroup.horizontal[0..4].map(&:prdist_std))
178
+ if group_std_avg > 1.0
179
+ message = <<~MESSAGE
180
+ The standard deviation of distances in the top 5 horizontal neighborhood groups is #{group_std_avg} which is high.
181
+ The standard deviation implies that control points neighborhoods making up this group can vary more than 1.0 in distance.
182
+ On highly optimized images (with many good control points) this standard deviation should be near 0.
183
+ This could mean that even after optimization, there may be a seam on an individual pair.
184
+ This also means that the images may represent a 3D object that has perspective differences.
185
+ MESSAGE
186
+ logger.warn message
187
+ end
188
+
189
+ group_control_points = NeighborhoodGroup.horizontal.first.control_points.count
190
+ total_control_points = Pair.horizontal.map(&:control_points).flatten.uniq(&:raw).count
191
+ group_control_point_ratio = group_control_points.to_f / total_control_points
192
+ if group_control_point_ratio < 0.2
193
+ message = <<~MESSAGE
194
+ Less than 20% (#{(group_control_point_ratio*100).round(4)}%) of horizontal control points in the best
195
+ horizontal neighborhood group (#{group_control_points}) make up the total number of horizontal control points (#{total_control_points}).
196
+ This means panosmosity failed to find a neighborhood group that would include enough similarities between control point distances.
197
+ There will very likely be seams horizontally.
198
+ MESSAGE
199
+ logger.warn message
200
+ recommendations << 'horizontal'
201
+ end
202
+
203
+ group_count = NeighborhoodGroup.vertical.count
204
+ if group_count < 5
205
+ message = <<~MESSAGE
206
+ Total number of vertical neighborhood groups is #{group_count} which is very low.
207
+ This can mean either low variation in control points distances or that not enough control points could be found.
208
+ MESSAGE
209
+ logger.warn message
210
+ end
211
+
212
+ group_std_avg = calculate_average(values: NeighborhoodGroup.vertical[0..4].map(&:prdist_std))
213
+ if group_std_avg > 1.0
214
+ message = <<~MESSAGE
215
+ The standard deviation of distances in the top 5 vertical neighborhood groups is #{group_std_avg} which is high.
216
+ The standard deviation implies that control points neighborhoods making up this group can vary more than 1.0 in distance.
217
+ On highly optimized images (with many good control points) this standard deviation should be near 0.
218
+ This could mean that even after optimization, there may be a seam on an individual pair.
219
+ This also means that the images may represent a 3D object that has perspective differences.
220
+ MESSAGE
221
+ logger.warn message
222
+ end
223
+
224
+ group_control_points = NeighborhoodGroup.vertical.first.control_points.count
225
+ total_control_points = Pair.vertical.map(&:control_points).flatten.uniq(&:raw).count
226
+ group_control_point_ratio = group_control_points.to_f / total_control_points
227
+ if group_control_point_ratio < 0.2
228
+ message = <<~MESSAGE
229
+ Less than 20% (#{(group_control_point_ratio*100).round(4)}%) of vertical control points in the best
230
+ vertical neighborhood group (#{group_control_points}) make up the total number of vertical control points (#{total_control_points}).
231
+ This means panosmosity failed to find a neighborhood group that would include enough similarities between control point distances.
232
+ There will very likely be seams vertically.
233
+ MESSAGE
234
+ logger.warn message
235
+ recommendations << 'vertical'
236
+ end
237
+
238
+ if recommendations.empty?
239
+ logger.warn 'No recommendations'
240
+ puts 'none'
241
+ else
242
+ logger.warn 'Recommendations are to regenerate with control points generated from calibration cards:'
243
+ puts recommendations.join(',')
244
+ end
245
+ end
143
246
  end
144
247
  end
@@ -13,6 +13,7 @@ module Panomosity
13
13
  convert_horizontal_lines
14
14
  convert_translation_parameters
15
15
  crop_centers
16
+ diagnose
16
17
  fix_conversion_errors
17
18
  fix_unconnected_image_pairs
18
19
  generate_border_line_control_points
@@ -39,7 +40,7 @@ module Panomosity
39
40
  @compare_file = File.new(@compare, 'r').read if @compare
40
41
  @logger = Panomosity.logger
41
42
 
42
- if options[:verbose] || options[:very_verbose]
43
+ if options[:verbose] || options[:verbosity] > 0
43
44
  @logger.level = Logger::DEBUG
44
45
  else
45
46
  @logger.level = Logger::INFO
@@ -233,6 +234,12 @@ module Panomosity
233
234
  save_file
234
235
  end
235
236
 
237
+ def diagnose
238
+ logger.info 'diagnosing errors'
239
+ panorama = Panorama.new(@input_file, @options)
240
+ panorama.diagnose
241
+ end
242
+
236
243
  def fix_conversion_errors
237
244
  logger.info 'fixing conversion errors'
238
245
  @lines = @input_file.each_line.map do |line|
@@ -249,7 +256,7 @@ module Panomosity
249
256
 
250
257
  def fix_unconnected_image_pairs
251
258
  logger.info 'fixing unconnected image pairs'
252
- panorama = Panorama.new(@input_file)
259
+ panorama = Panorama.new(@input_file, @options)
253
260
  @lines = panorama.fix_unconnected_image_pairs
254
261
  save_file
255
262
  end
@@ -466,7 +473,7 @@ module Panomosity
466
473
 
467
474
  def optimize
468
475
  logger.info 'optimizing'
469
- panorama = Panorama.new(@input_file)
476
+ panorama = Panorama.new(@input_file, @options)
470
477
  optimizer = Optimizer.new(panorama)
471
478
  optimizer.run
472
479
 
@@ -1,3 +1,3 @@
1
1
  module Panomosity
2
- VERSION = '0.1.21'
2
+ VERSION = '0.1.22'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panomosity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.21
4
+ version: 0.1.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Garcia
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-13 00:00:00.000000000 Z
11
+ date: 2018-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler