panomosity 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/exe/control_point_info.pl +1 -1
- data/lib/panomosity/control_point.rb +52 -2
- data/lib/panomosity/image.rb +19 -2
- data/lib/panomosity/panorama_variable.rb +64 -0
- data/lib/panomosity/runner.rb +141 -15
- data/lib/panomosity/version.rb +1 -1
- data/lib/panomosity.rb +5 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e32fb89b5812b7f726cf6c322423d4e816aa103bde59bd5deef4bd6fb2279d4
|
4
|
+
data.tar.gz: 2aae7a094ad7bccd73af5d6042a799e29cd4ce1bd0e1bdd81d187b24e82b33f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7d24392ffec1de2c6fb59b3ed8c4e03a59e91529ecc3a2a7c5d4bcca26383ea2a089dfd0f5e044fe2604c57b802324f6f4859532211b212808ea5a97aadc918
|
7
|
+
data.tar.gz: f41fae931324dc129bb4f9b8499f86d0d209dd9bcf9c396b768e988d9ab8abe62eec1032601335da697a7df69ebb9f26ae5c271b1fd040b66a6b3e8d6a021611
|
data/Gemfile.lock
CHANGED
data/exe/control_point_info.pl
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
module Panomosity
|
5
5
|
class ControlPoint
|
6
6
|
@@attributes = %i(n N x y X Y t)
|
7
|
+
@@calculated_attributes = %i(dist px py pdist conn_type)
|
7
8
|
|
8
9
|
def self.parse(pto_file, cp_type: nil, compact: false)
|
9
10
|
@control_points = pto_file.each_line.map do |line|
|
@@ -28,13 +29,44 @@ module Panomosity
|
|
28
29
|
else
|
29
30
|
@control_points
|
30
31
|
end
|
32
|
+
|
33
|
+
@control_points
|
31
34
|
end
|
32
35
|
|
33
36
|
def self.get_detailed_info(pto_file_path, cp_type: nil)
|
34
|
-
|
37
|
+
exe_dir = File.expand_path('../../exe', File.dirname(__FILE__))
|
38
|
+
control_point_info_executable = File.join(exe_dir, 'control_point_info.pl')
|
39
|
+
result = `#{control_point_info_executable} --input #{pto_file_path}`
|
35
40
|
parse(result, cp_type: cp_type, compact: true)
|
36
41
|
end
|
37
42
|
|
43
|
+
def self.calculate_distances(images, panorama_variable)
|
44
|
+
@control_points.each do |cp|
|
45
|
+
image1 = images.find { |i| cp.n1 == i.id }
|
46
|
+
image2 = images.find { |i| cp.n2 == i.id }
|
47
|
+
point1 = image1.to_cartesian(cp.x1, cp.y1)
|
48
|
+
point2 = image2.to_cartesian(cp.x2, cp.y2)
|
49
|
+
|
50
|
+
angle = Math.acos(point1[0] * point2[0] + point1[1] * point2[1] + point1[2] * point2[2])
|
51
|
+
radius = (panorama_variable.w / 2.0) / Math.tan((panorama_variable.v * Math::PI / 180) / 2)
|
52
|
+
|
53
|
+
distance = angle * radius
|
54
|
+
cp.dist = distance
|
55
|
+
|
56
|
+
# Pixel distance
|
57
|
+
x1 = (image1.w / 2.0) - cp.x1 + image1.d
|
58
|
+
y1 = (image1.h / 2.0) - cp.y1 + image1.e
|
59
|
+
x2 = (image2.w / 2.0) - cp.x2 + image2.d
|
60
|
+
y2 = (image2.h / 2.0) - cp.y2 + image2.e
|
61
|
+
|
62
|
+
pixel_distance = Math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
|
63
|
+
cp.px = x1 - x2
|
64
|
+
cp.py = y1 - y2
|
65
|
+
cp.pdist = pixel_distance
|
66
|
+
cp.conn_type = image1.d == image2.d ? :vertical : :horizontal
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
38
70
|
def self.all
|
39
71
|
@control_points
|
40
72
|
end
|
@@ -55,11 +87,20 @@ module Panomosity
|
|
55
87
|
end
|
56
88
|
end
|
57
89
|
|
90
|
+
def self.merge(first_set_control_points, second_set_control_points)
|
91
|
+
@control_points = first_set_control_points.map do |cp1|
|
92
|
+
similar_control_point = second_set_control_points.find { |cp2| cp1 == cp2 }
|
93
|
+
cp1.dist = similar_control_point.dist
|
94
|
+
cp1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
58
98
|
def initialize(attributes)
|
59
99
|
@attributes = attributes
|
60
100
|
# conform data types
|
61
101
|
@attributes.each do |key, value|
|
62
102
|
next if %i(raw).include?(key)
|
103
|
+
next unless value.is_a?(String)
|
63
104
|
if value.respond_to?(:include?) && value.include?('.')
|
64
105
|
@attributes[key] = value.to_f
|
65
106
|
else
|
@@ -76,7 +117,7 @@ module Panomosity
|
|
76
117
|
@attributes[key] = value
|
77
118
|
end
|
78
119
|
|
79
|
-
(@@attributes + %i(raw
|
120
|
+
(@@attributes + @@calculated_attributes + %i(raw)).each do |attr|
|
80
121
|
define_method(attr) do
|
81
122
|
@attributes[attr]
|
82
123
|
end
|
@@ -114,5 +155,14 @@ module Panomosity
|
|
114
155
|
line_values = @@attributes.map { |attribute| "#{attribute}#{self.send(attribute)}" }
|
115
156
|
"c #{line_values.join(' ')}\n"
|
116
157
|
end
|
158
|
+
|
159
|
+
def ==(o)
|
160
|
+
n1 == o.n1 &&
|
161
|
+
n2 == o.n2 &&
|
162
|
+
x1.floor == o.x1.floor &&
|
163
|
+
x2.floor == o.x2.floor &&
|
164
|
+
y1.floor == o.y1.floor &&
|
165
|
+
y2.floor == o.y2.floor
|
166
|
+
end
|
117
167
|
end
|
118
168
|
end
|
data/lib/panomosity/image.rb
CHANGED
@@ -106,10 +106,10 @@ module Panomosity
|
|
106
106
|
self[:TrY] * self.class.panosphere * height
|
107
107
|
end
|
108
108
|
|
109
|
-
def to_s
|
109
|
+
def to_s(options = {})
|
110
110
|
subline_values = (@@attributes - %i(Vm n)).map do |attribute|
|
111
111
|
value = self.send(attribute)
|
112
|
-
if @@equaled_attributes.include?(attribute)
|
112
|
+
if @@equaled_attributes.include?(attribute) && !options[:without_equal_signs]
|
113
113
|
if value == 0.0
|
114
114
|
"#{attribute}=#{value.to_i}"
|
115
115
|
else
|
@@ -139,5 +139,22 @@ module Panomosity
|
|
139
139
|
self[:e] = try
|
140
140
|
self
|
141
141
|
end
|
142
|
+
|
143
|
+
def to_cartesian(x1, y1)
|
144
|
+
px = (w / 2.0) - x1 + d
|
145
|
+
py = (h / 2.0) - y1 + e
|
146
|
+
rad = (w / 2.0) / Math.tan((v * Math::PI / 180) / 2)
|
147
|
+
r = self.r * Math::PI / 180
|
148
|
+
p = self.p * Math::PI / 180
|
149
|
+
y = self.y * Math::PI / 180
|
150
|
+
|
151
|
+
# Derived from multiplication of standard roll, pitch, and yaw matrices by the point vector (rad, px, py)
|
152
|
+
point = [Math.cos(p) * Math.cos(y) * rad - Math.sin(y) * Math.cos(p) * px + Math.sin(p) * py,
|
153
|
+
Math.sin(r) * Math.sin(p) * Math.cos(y) * rad + Math.sin(y) * Math.cos(r) * rad - Math.sin(r) * Math.sin(p) * Math.sin(y) * px + Math.cos(r) * Math.cos(y) * px - Math.sin(r) * Math.cos(p) * py,
|
154
|
+
-Math.sin(p) * Math.cos(r) * Math.cos(y) * rad + Math.sin(r) * Math.sin(y) * rad + Math.sin(p) * Math.sin(y) * Math.cos(r) * px + Math.sin(r) * Math.cos(y) * px + Math.cos(r) * Math.cos(p) * py]
|
155
|
+
magnitude = Math.sqrt(point[0] ** 2 + point[1] ** 2 + point[2] ** 2)
|
156
|
+
normalized_point = [point[0] / magnitude, point[1] / magnitude, point[2] / magnitude]
|
157
|
+
normalized_point
|
158
|
+
end
|
142
159
|
end
|
143
160
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Panomosity
|
2
|
+
class PanoramaVariable
|
3
|
+
@@attributes = %i(p w h f v n E R)
|
4
|
+
|
5
|
+
def self.parse(pto_file)
|
6
|
+
@panorama_variables = pto_file.each_line.map { |line| parse_line(line) }.compact
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.all
|
10
|
+
@panorama_variables
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parse_line(line)
|
14
|
+
parts = line.split(' ')
|
15
|
+
if parts.first == 'p'
|
16
|
+
data = parts.each_with_object({}) do |part, hash|
|
17
|
+
attribute = @@attributes.find { |attr| part[0] == attr.to_s }
|
18
|
+
next unless attribute
|
19
|
+
hash[attribute] = part.sub(attribute.to_s, '')
|
20
|
+
end
|
21
|
+
|
22
|
+
data[:raw] = line
|
23
|
+
|
24
|
+
new data
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(attributes)
|
29
|
+
@attributes = attributes
|
30
|
+
# conform data types
|
31
|
+
@attributes.each do |key, value|
|
32
|
+
next if %i(n raw).include?(key)
|
33
|
+
if value.respond_to?(:include?) && value.include?('.')
|
34
|
+
@attributes[key] = value.to_f
|
35
|
+
else
|
36
|
+
@attributes[key] = value.to_i
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def [](key)
|
42
|
+
@attributes[key]
|
43
|
+
end
|
44
|
+
|
45
|
+
def []=(key, value)
|
46
|
+
@attributes[key] = value
|
47
|
+
end
|
48
|
+
|
49
|
+
(@@attributes + %i(raw)).each do |attr|
|
50
|
+
define_method(attr) do
|
51
|
+
@attributes[attr]
|
52
|
+
end
|
53
|
+
|
54
|
+
define_method(:"#{attr}=") do |value|
|
55
|
+
@attributes[attr] = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
line_values = @@attributes.map { |attribute| "#{attribute}#{self.send(attribute)}" }
|
61
|
+
"p #{line_values.join(' ')}\n"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/panomosity/runner.rb
CHANGED
@@ -33,9 +33,9 @@ module Panomosity
|
|
33
33
|
@logger = Logger.new(STDOUT)
|
34
34
|
|
35
35
|
if options[:verbose]
|
36
|
-
@logger.level = Logger::INFO
|
37
|
-
else
|
38
36
|
@logger.level = Logger::DEBUG
|
37
|
+
else
|
38
|
+
@logger.level = Logger::INFO
|
39
39
|
end
|
40
40
|
|
41
41
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
@@ -89,7 +89,11 @@ module Panomosity
|
|
89
89
|
@lines = @input_file.each_line.map do |line|
|
90
90
|
image = images.find { |i| i.raw == line }
|
91
91
|
if image
|
92
|
-
|
92
|
+
if @options[:remove_equal_signs]
|
93
|
+
image.to_s(without_equal_signs: true)
|
94
|
+
else
|
95
|
+
image.to_s
|
96
|
+
end
|
93
97
|
else
|
94
98
|
next line
|
95
99
|
end
|
@@ -154,16 +158,16 @@ module Panomosity
|
|
154
158
|
# Since all images have been cropped, we need to change d,e params to move images based on how much was cropped
|
155
159
|
# Re-run commands that have been run at this point
|
156
160
|
logger.info 'rerunning commands'
|
157
|
-
@
|
161
|
+
@new_input = 'project_converted_translation_cropped.pto'
|
158
162
|
`match-n-shift --input #{@csv} -o project_cropped.pto`
|
159
163
|
`pto_var --opt=TrX,TrY project_cropped.pto -o project_pto_var_cropped.pto`
|
160
|
-
runner = Runner.new(@options.merge(input: 'project_pto_var_cropped.pto', output: @
|
164
|
+
runner = Runner.new(@options.merge(input: 'project_pto_var_cropped.pto', output: @new_input))
|
161
165
|
runner.run('convert_translation_parameters')
|
162
|
-
`pano_modify -p 0 --fov=AUTO -o #{@
|
166
|
+
`pano_modify -p 0 --fov=AUTO -o #{@new_input} #{@new_input}`
|
163
167
|
|
164
|
-
logger.info "Read new #{@
|
168
|
+
logger.info "Read new #{@new_input}"
|
165
169
|
# Read new input pto file
|
166
|
-
@input_file = File.new(@
|
170
|
+
@input_file = File.new(@new_input, 'r').read
|
167
171
|
images = Image.parse(@input_file)
|
168
172
|
ds = images.map(&:d).uniq.sort
|
169
173
|
es = images.map(&:e).uniq.sort
|
@@ -220,7 +224,108 @@ module Panomosity
|
|
220
224
|
def fix_unconnected_image_pairs
|
221
225
|
logger.info 'fixing unconnected image pairs'
|
222
226
|
images = Image.parse(@input_file)
|
227
|
+
panorama_variable = PanoramaVariable.parse(@input_file).first
|
228
|
+
ControlPoint.parse(@input_file)
|
229
|
+
control_points = ControlPoint.calculate_distances(images, panorama_variable)
|
230
|
+
|
231
|
+
horizontal_control_points, vertical_control_points = *control_points.partition { |cp| cp.conn_type == :horizontal }
|
232
|
+
control_points_of_pair = horizontal_control_points.group_by { |cp| [cp.n1, cp.n2] }.sort_by { |_, members| members.count }.last.last
|
233
|
+
logger.debug "found horizontal pair #{control_points_of_pair.first.n1} <> #{control_points_of_pair.first.n2} with #{control_points_of_pair.count} connections"
|
234
|
+
average_distance = control_points_of_pair.map(&:pdist).reduce(:+).to_f / control_points_of_pair.count
|
235
|
+
logger.debug "average distance #{average_distance}"
|
236
|
+
dist_std = Math.sqrt(control_points_of_pair.map { |cp| (cp.pdist - average_distance) ** 2 }.reduce(:+) / (control_points_of_pair.count - 1))
|
237
|
+
logger.debug "dist std: #{dist_std}"
|
238
|
+
horizontal_control_points_of_pair = control_points_of_pair.select { |cp| (cp.pdist - average_distance).abs < dist_std }
|
239
|
+
logger.info "removed #{control_points_of_pair.count - horizontal_control_points_of_pair.count} outliers"
|
240
|
+
new_average_distance = horizontal_control_points_of_pair.map(&:pdist).reduce(:+).to_f / horizontal_control_points_of_pair.count
|
241
|
+
logger.info "new average #{new_average_distance}"
|
242
|
+
|
243
|
+
control_points_of_pair = vertical_control_points.group_by { |cp| [cp.n1, cp.n2] }.sort_by { |_, members| members.count }.last.last
|
244
|
+
logger.debug "found vertical pair #{control_points_of_pair.first.n1} <> #{control_points_of_pair.first.n2} with #{control_points_of_pair.count} connections"
|
245
|
+
average_distance = control_points_of_pair.map(&:pdist).reduce(:+).to_f / control_points_of_pair.count
|
246
|
+
logger.debug "average distance #{average_distance}"
|
247
|
+
dist_std = Math.sqrt(control_points_of_pair.map { |cp| (cp.pdist - average_distance) ** 2 }.reduce(:+) / (control_points_of_pair.count - 1))
|
248
|
+
logger.debug "dist std: #{dist_std}"
|
249
|
+
vertical_control_points_of_pair = control_points_of_pair.select { |cp| (cp.pdist - average_distance).abs < dist_std }
|
250
|
+
logger.info "removed #{control_points_of_pair.count - vertical_control_points_of_pair.count} outliers"
|
251
|
+
new_average_distance = vertical_control_points_of_pair.map(&:pdist).reduce(:+).to_f / vertical_control_points_of_pair.count
|
252
|
+
logger.info "new average #{new_average_distance}"
|
253
|
+
|
254
|
+
logger.info 'finding unconnected image pairs'
|
255
|
+
ds = images.map(&:d).uniq.sort
|
256
|
+
es = images.map(&:e).uniq.sort
|
257
|
+
|
258
|
+
unconnected_image_pairs = []
|
259
|
+
# horizontal connection checking
|
260
|
+
es.each do |e|
|
261
|
+
ds.each_with_index do |d, index|
|
262
|
+
next if index == (ds.count - 1)
|
263
|
+
image_1 = images.find { |i| i.e == e && i.d == d }
|
264
|
+
image_2 = images.find { |i| i.e == e && i.d == ds[index+1] }
|
265
|
+
connected = control_points.any? { |cp| (cp.n1 == image_1.id && cp.n2 == image_2.id) || (cp.n1 == image_2.id && cp.n2 == image_1.id) }
|
266
|
+
unconnected_image_pairs << { type: :horizontal, pair: [image_1, image_2].sort_by(&:id) } unless connected
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# vertical connection checking
|
271
|
+
ds.each do |d|
|
272
|
+
es.each_with_index do |e, index|
|
273
|
+
next if index == (es.count - 1)
|
274
|
+
image_1 = images.find { |i| i.d == d && i.e == e }
|
275
|
+
image_2 = images.find { |i| i.d == d && i.e == es[index+1] }
|
276
|
+
connected = control_points.any? { |cp| (cp.n1 == image_1.id && cp.n2 == image_2.id) || (cp.n1 == image_2.id && cp.n2 == image_1.id) }
|
277
|
+
unconnected_image_pairs << { type: :vertical, pair: [image_1, image_2].sort_by(&:id) } unless connected
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
logger.info unconnected_image_pairs.map { |i| { type: i[:type], pair: i[:pair].map(&:id) } }
|
282
|
+
|
283
|
+
logger.info 'finding control points with unrealistic distances (<1)'
|
284
|
+
fake_control_points = control_points.select { |cp| cp.pdist <= 1.0 }
|
285
|
+
|
286
|
+
logger.info 'writing new control points'
|
287
|
+
control_point_lines_started = false
|
288
|
+
@lines = @input_file.each_line.map do |line|
|
289
|
+
cp = ControlPoint.parse_line(line)
|
290
|
+
if cp.nil?
|
291
|
+
# Control point lines ended
|
292
|
+
if control_point_lines_started
|
293
|
+
control_point_lines_started = false
|
294
|
+
unconnected_image_pairs.map do |pair|
|
295
|
+
if pair[:type] == :horizontal
|
296
|
+
control_point = horizontal_control_points_of_pair.first
|
297
|
+
else
|
298
|
+
control_point = vertical_control_points_of_pair.first
|
299
|
+
end
|
300
|
+
|
301
|
+
control_point[:n] = pair[:pair].first.id
|
302
|
+
control_point[:N] = pair[:pair].last.id
|
303
|
+
logger.debug "adding control point connecting #{control_point.n1} <> #{control_point.n2}"
|
304
|
+
control_point.to_s
|
305
|
+
end + [line]
|
306
|
+
else
|
307
|
+
next line
|
308
|
+
end
|
309
|
+
else
|
310
|
+
control_point_lines_started = true
|
311
|
+
fake_control_point = fake_control_points.find { |cp| cp.raw == line }
|
312
|
+
if fake_control_point
|
313
|
+
if fake_control_point.conn_type == :horizontal
|
314
|
+
control_point = horizontal_control_points_of_pair.first
|
315
|
+
else
|
316
|
+
control_point = vertical_control_points_of_pair.first
|
317
|
+
end
|
318
|
+
control_point[:n] = fake_control_point[:n]
|
319
|
+
control_point[:N] = fake_control_point[:N]
|
320
|
+
logger.debug "replacing unrealistic control point connecting #{control_point.n1} <> #{control_point.n2}"
|
321
|
+
control_point.to_s
|
322
|
+
else
|
323
|
+
next line
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end.compact.flatten
|
223
327
|
|
328
|
+
save_file
|
224
329
|
end
|
225
330
|
|
226
331
|
def generate_border_line_control_points
|
@@ -348,19 +453,40 @@ module Panomosity
|
|
348
453
|
end
|
349
454
|
|
350
455
|
def get_detailed_control_point_info
|
351
|
-
logger.info '
|
456
|
+
logger.info 'getting detailed control point info'
|
352
457
|
|
353
458
|
images = Image.parse(@input_file)
|
354
|
-
|
459
|
+
panorama_variable = PanoramaVariable.parse(@input_file).first
|
460
|
+
first_set_control_points = ControlPoint.parse(@input_file)
|
461
|
+
|
462
|
+
@new_input = 'project_remove_equal_signs.pto'
|
463
|
+
runner = Runner.new(@options.merge(input: @input, output: @new_input, remove_equal_signs: true))
|
464
|
+
runner.run('convert_equaled_image_parameters')
|
465
|
+
@input_file = File.new(@new_input, 'r').read
|
466
|
+
|
467
|
+
second_set_control_points = ControlPoint.get_detailed_info(@new_input)
|
468
|
+
control_points = ControlPoint.merge(first_set_control_points, second_set_control_points)
|
355
469
|
control_points.each do |cp|
|
356
470
|
image1 = images.find { |i| cp.n1 == i.id }
|
357
471
|
image2 = images.find { |i| cp.n2 == i.id }
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
472
|
+
point1 = image1.to_cartesian(cp.x1, cp.y1)
|
473
|
+
point2 = image2.to_cartesian(cp.x2, cp.y2)
|
474
|
+
|
475
|
+
angle = Math.acos(point1[0] * point2[0] + point1[1] * point2[1] + point1[2] * point2[2])
|
476
|
+
radius = (panorama_variable.w / 2.0) / Math.tan((panorama_variable.v * Math::PI / 180) / 2)
|
477
|
+
|
478
|
+
x1 = (image1.w / 2.0) - cp.x1 + image1.d
|
479
|
+
y1 = (image1.h / 2.0) - cp.y1 + image1.e
|
480
|
+
x2 = (image2.w / 2.0) - cp.x2 + image2.d
|
481
|
+
y2 = (image2.h / 2.0) - cp.y2 + image2.e
|
482
|
+
|
483
|
+
dist = Math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
|
484
|
+
|
485
|
+
dr = angle * radius
|
486
|
+
|
487
|
+
type = image1.d == image2.d ? :vertical : :horizontal
|
488
|
+
logger.debug "#{cp.to_s.sub(/\n/, '')} dist #{dr} pixel_dist #{x1-x2},#{y1-y2},#{dist} type #{type}"
|
362
489
|
end
|
363
|
-
logger.debug "avg #{control_points.map(&:dist).reduce(:+)/control_points.count.to_f}"
|
364
490
|
end
|
365
491
|
|
366
492
|
def merge_image_parameters
|
data/lib/panomosity/version.rb
CHANGED
data/lib/panomosity.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'panomosity/control_point'
|
2
2
|
require 'panomosity/image'
|
3
3
|
require 'panomosity/optimisation_variable'
|
4
|
+
require 'panomosity/panorama_variable'
|
4
5
|
require 'panomosity/runner'
|
5
6
|
require 'panomosity/version'
|
6
7
|
require 'pathname'
|
@@ -35,6 +36,10 @@ module Panomosity
|
|
35
36
|
options[:without_cropping] = wc
|
36
37
|
end
|
37
38
|
|
39
|
+
parser.on('--remove-equal-signs', 'Do not crop when running "crop_centers" (usually when the original run failed)') do |eq|
|
40
|
+
options[:remove_equal_signs] = eq
|
41
|
+
end
|
42
|
+
|
38
43
|
parser.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
|
39
44
|
options[:verbose] = v
|
40
45
|
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.
|
4
|
+
version: 0.1.4
|
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
|
+
date: 2018-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- lib/panomosity/control_point.rb
|
79
79
|
- lib/panomosity/image.rb
|
80
80
|
- lib/panomosity/optimisation_variable.rb
|
81
|
+
- lib/panomosity/panorama_variable.rb
|
81
82
|
- lib/panomosity/runner.rb
|
82
83
|
- lib/panomosity/version.rb
|
83
84
|
- panomosity.gemspec
|