tracksperanto 2.12.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/DEVELOPER_DOCS.rdoc +15 -8
- data/History.txt +21 -14
- data/Rakefile +1 -0
- data/bin/tracksperanto +30 -29
- data/lib/export/flame_stabilizer_cornerpin.rb +4 -2
- data/lib/export/pfmatchit.rb +8 -1
- data/lib/export/pftrack.rb +8 -1
- data/lib/import/pftrack.rb +4 -1
- data/lib/import/syntheyes.rb +2 -2
- data/lib/pipeline/base.rb +13 -13
- data/lib/{middleware → tools}/base.rb +7 -7
- data/lib/{middleware → tools}/crop.rb +3 -3
- data/lib/{middleware → tools}/flip.rb +2 -2
- data/lib/{middleware → tools}/flop.rb +2 -2
- data/lib/{middleware → tools}/golden.rb +2 -2
- data/lib/{middleware → tools}/length_cutoff.rb +2 -2
- data/lib/{middleware → tools}/lens_disto.rb +2 -2
- data/lib/{middleware → tools}/lerp.rb +2 -2
- data/lib/{middleware → tools}/lint.rb +1 -1
- data/lib/{middleware → tools}/move_to_first.rb +3 -3
- data/lib/{middleware → tools}/pad.rb +2 -2
- data/lib/{middleware → tools}/prefix.rb +2 -2
- data/lib/{middleware → tools}/reformat.rb +3 -3
- data/lib/{middleware → tools}/scaler.rb +1 -1
- data/lib/{middleware → tools}/shift.rb +2 -2
- data/lib/{middleware → tools}/slipper.rb +1 -1
- data/lib/tools/start_trim.rb +17 -0
- data/lib/tracksperanto/pf_coords.rb +9 -0
- data/lib/tracksperanto/simple_export.rb +1 -1
- data/lib/tracksperanto/uv_coordinates.rb +15 -13
- data/lib/tracksperanto.rb +16 -15
- data/test/export/samples/ref_PFMatchit.2dt +39 -39
- data/test/export/samples/ref_PFTrack.2dt +39 -39
- data/test/export/samples/ref_PFTrack5.2dt +39 -39
- data/test/export/samples/ref_Syntheyes.txt +39 -39
- data/test/import/test_pftrack_import.rb +5 -5
- data/test/import/test_shake_script_import.rb +9 -1
- data/test/import/test_syntheyes_import.rb +3 -3
- data/test/subpixel/Flame_Smk2013_SubpixSample.stabilizer +310 -0
- data/test/subpixel/julik_pftrack.txt +14 -0
- data/test/subpixel/shake_subpix_v01.shk +308 -0
- data/test/subpixel/subpix_import_test.rb +75 -0
- data/test/subpixel/subpixel_grid.ifl +1 -0
- data/test/subpixel/subpixel_grid.sni +0 -0
- data/test/subpixel/subpixel_grid.tif +0 -0
- data/test/subpixel/sy_subpix_2dpaths.txt +4 -0
- data/test/test_const_name.rb +2 -2
- data/test/test_pipeline.rb +10 -10
- data/test/test_tracksperanto.rb +11 -11
- data/test/test_uv_coords.rb +29 -0
- data/test/{middleware → tools}/test_crop_middleware.rb +4 -4
- data/test/{middleware → tools}/test_flip_middleware.rb +3 -3
- data/test/{middleware → tools}/test_flop_middleware.rb +3 -3
- data/test/{middleware → tools}/test_golden_middleware.rb +3 -3
- data/test/{middleware → tools}/test_length_cutoff_middleware.rb +5 -5
- data/test/{middleware → tools}/test_lens_middleware.rb +9 -9
- data/test/{middleware → tools}/test_lerp_middleware.rb +3 -3
- data/test/{middleware → tools}/test_lint_middleware.rb +11 -11
- data/test/{middleware → tools}/test_move_to_first_frame_middleware.rb +3 -3
- data/test/{middleware → tools}/test_pad_middleware.rb +4 -4
- data/test/{middleware → tools}/test_prefix.rb +5 -5
- data/test/{middleware → tools}/test_reformat_middleware.rb +5 -5
- data/test/{middleware → tools}/test_scaler_middleware.rb +7 -7
- data/test/{middleware → tools}/test_shift_middleware.rb +4 -4
- data/test/{middleware → tools}/test_slip_middleware.rb +5 -5
- data/test/{middleware → tools}/test_start_trim_middleware.rb +3 -3
- data/tracksperanto.gemspec +45 -35
- metadata +46 -36
- data/lib/middleware/start_trim.rb +0 -17
data/DEVELOPER_DOCS.rdoc
CHANGED
@@ -18,6 +18,13 @@ in the Gemfile plus Bundler. Please develop against the git repo checkout since
|
|
18
18
|
* Carry your development, in your own branch or feature branch
|
19
19
|
* File a pull request or send a patch to info at guerilla-di.org
|
20
20
|
|
21
|
+
=== Internal tracker representation
|
22
|
+
|
23
|
+
The trackers are represented by Tracker objects, which work like addressable hashes per frame number. The Tracker objects
|
24
|
+
contain Keyframe objects, and those in turn contain coordinates. The coordinates are stored in absolute pixels, relative to
|
25
|
+
the zero coordinate in the lower left corner. The absolute left/bottom of the image has coordinates 0,0 (at the lower left corner of the
|
26
|
+
first pixel) and 0.5x0.5 in the middle of the leftmost lower pixel.
|
27
|
+
|
21
28
|
=== Importing your own formats
|
22
29
|
|
23
30
|
You can easily write a Tracksperanto import module - refer to Tracksperanto::Import::Base
|
@@ -33,14 +40,14 @@ the exporter should work with streams (smaller parts of the file being exported
|
|
33
40
|
|
34
41
|
=== Ading your own processing steps
|
35
42
|
|
36
|
-
You probably want to write a
|
37
|
-
or their data. A
|
38
|
-
modules or each other, so you can stack different
|
43
|
+
You probably want to write a Tool (consult the Tracksperanto::Tool::Base docs) if you need some processing applied to the tracks
|
44
|
+
or their data. A Tool is just like an export module, except that instead it sits between the exporter and the exporting routine. Tools wrap export
|
45
|
+
modules or each other, so you can stack different tool modules together (like "scale first, then move").
|
39
46
|
|
40
47
|
=== Writing your own processing routines
|
41
48
|
|
42
49
|
You probably want to write a descendant of Tracksperanto::Pipeline::Base. This is a class that manages a conversion from start to finish, including detecting the
|
43
|
-
input format, allocating output files and building a chain of
|
50
|
+
input format, allocating output files and building a chain of Tools to process the export. If you want to make a GUI for Tracksperanto you will likely need
|
44
51
|
to write your own Pipeline class or reimplement parts of it.
|
45
52
|
|
46
53
|
=== Reporting status from long-running operations
|
@@ -74,11 +81,11 @@ the software user-friendly. A well-behaved Tracksperanto module should manage it
|
|
74
81
|
destination_file = File.open("exported_file.other", "wb")
|
75
82
|
some_exporter = Tracksperanto.get_exporter("flamestabilizer").new(destination_file)
|
76
83
|
|
77
|
-
# Now add some
|
78
|
-
scaler =
|
79
|
-
# ... and a slip.
|
84
|
+
# Now add some tools, for example a Scale
|
85
|
+
scaler = Tool::Scaler.new(some_exporter, :x_factor => 2)
|
86
|
+
# ... and a slip. Tools wrap exporters and other tools, so you can chain them
|
80
87
|
# ad nauseam
|
81
|
-
slipper =
|
88
|
+
slipper = Tool::Slipper.new(scaler, :offset => 2)
|
82
89
|
|
83
90
|
# Now when we send export commands to the Slipper it will play them through
|
84
91
|
# to the Scaler and the Scaler in turn will send commands to the exporter.
|
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 3.0.0
|
2
|
+
|
3
|
+
* Middleware renamed to Tools
|
4
|
+
* Multiple subpixel accuracy tests added
|
5
|
+
* Subpixel accuracy fixed for Syntheyes modules
|
6
|
+
* Subpixel accuracy fixed for PFTrack modules
|
7
|
+
|
1
8
|
=== 2.12.0
|
2
9
|
|
3
10
|
* Add an export module for Nuke's CameraTracker node. This is just like the Shake format, except that tracker names have to be special.
|
@@ -21,7 +28,7 @@
|
|
21
28
|
|
22
29
|
=== 2.9.9
|
23
30
|
|
24
|
-
* Add lens distortion
|
31
|
+
* Add lens distortion tool. Adds the possibility to remove or add Syntheyes lens distortion to your plates.
|
25
32
|
|
26
33
|
=== 2.9.8
|
27
34
|
|
@@ -34,7 +41,7 @@
|
|
34
41
|
=== 2.9.6
|
35
42
|
|
36
43
|
* Add Nuke Reconcile3D support
|
37
|
-
* Add
|
44
|
+
* Add Tool::Base.parameters for automatic GUI building
|
38
45
|
|
39
46
|
=== 2.9.5
|
40
47
|
|
@@ -71,7 +78,7 @@
|
|
71
78
|
|
72
79
|
=== 2.8.5
|
73
80
|
|
74
|
-
* Add Pad and Crop
|
81
|
+
* Add Pad and Crop tools for fixing botched telecine and anamorphic Alexa
|
75
82
|
|
76
83
|
=== 2.8.2
|
77
84
|
|
@@ -85,7 +92,7 @@
|
|
85
92
|
=== 2.8.1
|
86
93
|
|
87
94
|
* Fix the bug that MatchMover importer would always assume the sequence starting on frame 1
|
88
|
-
* Fix the bug that Lint
|
95
|
+
* Fix the bug that Lint tool would raise when the export was started from negative frame offsets
|
89
96
|
|
90
97
|
=== 2.8.0
|
91
98
|
|
@@ -193,7 +200,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
193
200
|
|
194
201
|
=== 2.0.2
|
195
202
|
* Compatible with Ruby 1.9.2
|
196
|
-
* Scaler
|
203
|
+
* Scaler tool now supports negative scaling factors
|
197
204
|
|
198
205
|
=== 2.0.0
|
199
206
|
* Bugfix for PFTrack exports to contain cross-platform linebreaks (rn instead of n)
|
@@ -208,7 +215,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
208
215
|
* Very minor changes and improvements
|
209
216
|
* The app will now tell you when you try to feed it an empty file
|
210
217
|
* Change Synetheyes exports to start with a standard frame and not a keyframe to make 1-frame trackers work
|
211
|
-
* Adds a flip
|
218
|
+
* Adds a flip tool to mirror a tracked comp
|
212
219
|
|
213
220
|
=== 1.9.6
|
214
221
|
|
@@ -241,7 +248,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
241
248
|
=== 1.9.0
|
242
249
|
|
243
250
|
* Use proper progress bars
|
244
|
-
* Allow proper chaining of
|
251
|
+
* Allow proper chaining of tools in the commandline app - you can now apply many tools of the same nature in chain, and they will be ordered correctly
|
245
252
|
* Small rewrites to Pipeline::Base (changes API slightly - please consult the docs)
|
246
253
|
|
247
254
|
=== 1.8.4
|
@@ -270,7 +277,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
270
277
|
* Introduce an intentional gap in the reference exports to test trackers with gaps
|
271
278
|
* Export Syntheyes paths as normal frames, not as keyframes. This produces better solves by not overconstraining the solver
|
272
279
|
(Without this TransitionFrms, a crucial parameter in SY, seizes to work)
|
273
|
-
* Add a LengthCutoff
|
280
|
+
* Add a LengthCutoff tool that allows you to remove trackers that have less than X keyframes in them from the export
|
274
281
|
|
275
282
|
=== 1.7.3
|
276
283
|
|
@@ -278,7 +285,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
278
285
|
|
279
286
|
=== 1.7.2
|
280
287
|
|
281
|
-
* Add a Lerp
|
288
|
+
* Add a Lerp tool that linearly interpolates missing keyframes (USE CAREFULLY!)
|
282
289
|
* Prevent the Shake lexer from walking into the woods on files that are certainly wrong
|
283
290
|
* Export proper project length with Nuke scripts
|
284
291
|
* Ensure preamble for Nuke exports does not get overriden in width/height
|
@@ -322,7 +329,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
322
329
|
|
323
330
|
=== 1.6.2
|
324
331
|
|
325
|
-
* Fixes the Reformat
|
332
|
+
* Fixes the Reformat tool to not suppress the end_export call. Crucial for exporters that
|
326
333
|
use end_export to finalize output
|
327
334
|
|
328
335
|
=== 1.6.0
|
@@ -332,7 +339,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
332
339
|
|
333
340
|
=== 1.5.7
|
334
341
|
|
335
|
-
* Add a Prefix
|
342
|
+
* Add a Prefix tool that prefixes tracker names
|
336
343
|
|
337
344
|
=== 1.5.6
|
338
345
|
|
@@ -350,7 +357,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
350
357
|
=== 1.5.2
|
351
358
|
|
352
359
|
* Fix Windows-specific issue (Tempfile-related) in the Equalizer4 exporter
|
353
|
-
* Add Export::Base#just_export and
|
360
|
+
* Add Export::Base#just_export and Tool::Base#just_export
|
354
361
|
|
355
362
|
=== 1.5.0
|
356
363
|
|
@@ -392,8 +399,8 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
392
399
|
|
393
400
|
* Add experimental MatchMoverPro import and export support
|
394
401
|
* Rewrite the Shake parser, support MatchMove and Stabilize nodes and many tracks per node
|
395
|
-
* Officially add and test the Reformat
|
396
|
-
* Remove the Close
|
402
|
+
* Officially add and test the Reformat tool
|
403
|
+
* Remove the Close tool and close IOs automatically at pipeline end
|
397
404
|
* Much improved documentation
|
398
405
|
* Use IO as base for all the parsers (if a parser needs a string it will have to read by himself)
|
399
406
|
* Much improved test coverage
|
data/Rakefile
CHANGED
data/bin/tracksperanto
CHANGED
@@ -22,26 +22,26 @@ def disclaimer
|
|
22
22
|
end
|
23
23
|
|
24
24
|
options = {}
|
25
|
-
$
|
25
|
+
$tools = []
|
26
26
|
writer_class_name = nil
|
27
27
|
readers = Tracksperanto.importer_names
|
28
28
|
writers = Tracksperanto.exporter_names
|
29
29
|
|
30
30
|
op = OptionParser.new
|
31
31
|
|
32
|
-
def
|
32
|
+
def tool(*name_option_and_default_value)
|
33
33
|
Proc.new do |value|
|
34
34
|
name, option, default_value = name_option_and_default_value
|
35
35
|
v = value.nil? ? default_value : value
|
36
|
-
|
37
|
-
|
36
|
+
tool_tuple = [name]
|
37
|
+
tool_tuple.push({option => v}) if option
|
38
38
|
|
39
|
-
$
|
39
|
+
$tools.push(tool_tuple)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
Tracksperanto.
|
43
|
+
def toold(name)
|
44
|
+
Tracksperanto.get_tool(name).action_description
|
45
45
|
end
|
46
46
|
|
47
47
|
def list_exporters(dest = $stderr)
|
@@ -77,43 +77,44 @@ op.on(" -w", "--width WIDTH_IN_PIXELS", Integer, "Absolute input comp width in p
|
|
77
77
|
op.on(" -h", "--height HEIGHT_IN_PIXELS", Integer, "Absolute input comp height in pixels (will try to autodetect)") {|w| options[:height] = w }
|
78
78
|
op.on(" -o", "--only EXPORTER_NAME", String, "Only export the selected format, format must be one of: #{f(writers)}") { |f| writer_class_name = f }
|
79
79
|
|
80
|
-
op.on(" -xs", "--xscale X_SCALING_FACTOR", Float,
|
80
|
+
op.on(" -xs", "--xscale X_SCALING_FACTOR", Float, toold("Scaler"), &tool("Scaler", :x_factor))
|
81
81
|
|
82
|
-
op.on(" -pad", "--pad PAD_FRACTION_VALUES_COMMA_SEPARATED", String,
|
82
|
+
op.on(" -pad", "--pad PAD_FRACTION_VALUES_COMMA_SEPARATED", String, toold("Pad")) do | pads|
|
83
83
|
left, right, top, bottom = pads.split(",").map{|e| e.to_f }
|
84
|
-
$
|
84
|
+
$tools.push(["Pad", {"left_pad" => left, "right_pad"=> right, "top_pad" => top, "bottom_pad" => bottom}])
|
85
85
|
end
|
86
86
|
|
87
87
|
op.on(" -u", "--undistort K_AND_KCUBE_COMMA_SEPARATED", String, "Remove lens distortion using the Syntheyes algorithm") do | coefficients |
|
88
88
|
k, kcube = coefficients.split(",").map{|e| e.to_f }
|
89
|
-
$
|
89
|
+
$tools.push(["LensDisto", {"k" => k, "kcube"=> kcube, "remove" => true}])
|
90
90
|
end
|
91
91
|
|
92
92
|
op.on(" -d", "--distort K_AND_KCUBE_COMMA_SEPARATED", String, "Add lens distortion using the Syntheyes algorithm") do | coefficients |
|
93
93
|
k, kcube = coefficients.split(",").map{|e| e.to_f }
|
94
|
-
$
|
94
|
+
$tools.push(["LensDisto", {"k" => k, "kcube"=> kcube, "remove" => false}])
|
95
95
|
end
|
96
96
|
|
97
|
-
op.on(" -crop", "--crop CROP_VALUES_COMMA_SEPARATED", String,
|
97
|
+
op.on(" -crop", "--crop CROP_VALUES_COMMA_SEPARATED", String, toold("Crop")) do | pads|
|
98
98
|
left, right, top, bottom = pads.split(",").map{|e| e.to_i }
|
99
|
-
$
|
99
|
+
$tools.push(["Crop", {"left" => left, "right"=> right, "top" => top, "bottom" => bottom}])
|
100
100
|
end
|
101
101
|
|
102
|
-
op.on(" -ys", "--yscale Y_SCALING_FACTOR", Float,
|
103
|
-
op.on(" -t", "--trim", Float,
|
104
|
-
op.on(" -s", "--slip FRAMES", Integer,
|
105
|
-
op.on(" -g", "--golden",
|
106
|
-
op.on(" -m", "--min-length LENGTH_IN_FRAMES", Integer,
|
107
|
-
op.on(" -p", "--prefix PREFIX", String,
|
108
|
-
op.on("--
|
109
|
-
op.on("--
|
110
|
-
op.on("--
|
102
|
+
op.on(" -ys", "--yscale Y_SCALING_FACTOR", Float, toold("Scaler"), &tool("Scaler", :y_factor))
|
103
|
+
op.on(" -t", "--trim", Float, toold("StartTrim"), &tool("StartTrim")) # Before slip!
|
104
|
+
op.on(" -s", "--slip FRAMES", Integer, toold("Slipper"), &tool("Slipper", :slip))
|
105
|
+
op.on(" -g", "--golden", toold("Golden"), &tool("Golden"))
|
106
|
+
op.on(" -m", "--min-length LENGTH_IN_FRAMES", Integer, toold("LengthCutoff"), &tool("LengthCutoff", :min_length))
|
107
|
+
op.on(" -p", "--prefix PREFIX", String, toold("Prefix"), &tool("Prefix", :prefix))
|
108
|
+
op.on(" -as", "--autoslip", toold("MoveToFirst"), &tool("MoveToFirst"))
|
109
|
+
op.on("--lerp", toold("Lerp"), &tool("Lerp"))
|
110
|
+
op.on("--flip", toold("Flip"), &tool("Flip"))
|
111
|
+
op.on("--flop", toold("Flop"), &tool("Flop"))
|
111
112
|
|
112
113
|
# TODO - multiparameters
|
113
|
-
op.on(" -rx", "--reformat-x NEW_PIX_WIDTH", Integer, "Reformat the comp to this width and scale all tracks to it", &
|
114
|
-
op.on(" -ry", "--reformat-y NEW_PIX_HEIGHT", Integer, "Reformat the comp to this height and scale all tracks to it", &
|
115
|
-
op.on(" -xm", "--xshift X_IN_PIXELS", Float, "Move the points left or right", &
|
116
|
-
op.on(" -ym", "--yshift Y_IN_PIXELS", Float, "Move the points up or down", &
|
114
|
+
op.on(" -rx", "--reformat-x NEW_PIX_WIDTH", Integer, "Reformat the comp to this width and scale all tracks to it", &tool("Reformat", :width))
|
115
|
+
op.on(" -ry", "--reformat-y NEW_PIX_HEIGHT", Integer, "Reformat the comp to this height and scale all tracks to it", &tool("Reformat", :height))
|
116
|
+
op.on(" -xm", "--xshift X_IN_PIXELS", Float, "Move the points left or right", &tool("Shift", :x_shift))
|
117
|
+
op.on(" -ym", "--yshift Y_IN_PIXELS", Float, "Move the points up or down", &tool("Shift", :y_shift))
|
117
118
|
|
118
119
|
|
119
120
|
op.on("--list-exporters", "Show available export modules") do
|
@@ -152,7 +153,7 @@ progress = lambda do |percent,message|
|
|
152
153
|
end
|
153
154
|
|
154
155
|
begin
|
155
|
-
pipe = Tracksperanto::Pipeline::Base.new(:progress_block => progress, :
|
156
|
+
pipe = Tracksperanto::Pipeline::Base.new(:progress_block => progress, :tool_tuples => $tools)
|
156
157
|
pipe.exporters = [Tracksperanto.get_exporter(writer_class_name)] if writer_class_name
|
157
158
|
pipe.run(input_file, options)
|
158
159
|
pbar.finish
|
@@ -165,7 +166,7 @@ rescue Tracksperanto::UnknownImporterError => damn
|
|
165
166
|
$stderr.puts damn.message
|
166
167
|
list_importers($stderr)
|
167
168
|
fail "Unknown importer"
|
168
|
-
rescue Tracksperanto::
|
169
|
+
rescue Tracksperanto::UnknownToolError => damn
|
169
170
|
$stderr.puts damn.message
|
170
171
|
fail "This is a bug, please report it"
|
171
172
|
rescue Exception => damn
|
@@ -17,7 +17,7 @@ class Tracksperanto::Export::FlameStabilizerCornerpin < Tracksperanto::Export::F
|
|
17
17
|
# _______/
|
18
18
|
# |
|
19
19
|
# BL -> BR
|
20
|
-
# This "kinda
|
20
|
+
# This "kinda tool" ensures that this is indeed taking place
|
21
21
|
class Sorter < DelegateClass(Tracksperanto::Export::Base)
|
22
22
|
include Tracksperanto::SimpleExport # so that it calls OUR methods
|
23
23
|
|
@@ -68,7 +68,9 @@ class Tracksperanto::Export::FlameStabilizerCornerpin < Tracksperanto::Export::F
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
# Initialize the exporter with a preconfigured sorter around it
|
71
|
+
# Initialize the exporter with a preconfigured sorter around it.
|
72
|
+
# When this object receives the commands they will come from the Sorter instead,
|
73
|
+
# and the trackers will already be in their Z-order
|
72
74
|
def self.new(*arguments)
|
73
75
|
object = super
|
74
76
|
Sorter.new(object)
|
data/lib/export/pfmatchit.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
# Export for PFMatchit
|
3
3
|
class Tracksperanto::Export::PFMatchit < Tracksperanto::Export::Base
|
4
4
|
|
5
|
+
include Tracksperanto::PFCoords
|
6
|
+
|
5
7
|
KEYFRAME_TEMPLATE = "%s %.3f %.3f %.3f"
|
6
8
|
|
7
9
|
def self.desc_and_extension
|
@@ -12,6 +14,11 @@ class Tracksperanto::Export::PFMatchit < Tracksperanto::Export::Base
|
|
12
14
|
"PFTrack2011/PFMatchit .txt file (single camera)"
|
13
15
|
end
|
14
16
|
|
17
|
+
def start_export(w, h)
|
18
|
+
@width = w
|
19
|
+
@height = h
|
20
|
+
end
|
21
|
+
|
15
22
|
def start_tracker_segment(tracker_name)
|
16
23
|
# Setup for the next tracker
|
17
24
|
@frame_count = 0
|
@@ -36,7 +43,7 @@ class Tracksperanto::Export::PFMatchit < Tracksperanto::Export::Base
|
|
36
43
|
|
37
44
|
def export_point(frame, abs_float_x, abs_float_y, float_residual)
|
38
45
|
@frame_count += 1
|
39
|
-
line = KEYFRAME_TEMPLATE % [frame_number(frame), abs_float_x, abs_float_y, float_residual / 8]
|
46
|
+
line = KEYFRAME_TEMPLATE % [frame_number(frame), to_pfcoord(abs_float_x), to_pfcoord(abs_float_y), float_residual / 8]
|
40
47
|
@tracker_io.write(line)
|
41
48
|
@tracker_io.write(linebreak)
|
42
49
|
end
|
data/lib/export/pftrack.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
# Export for PFTrack .2dt files
|
3
3
|
class Tracksperanto::Export::PFTrack4 < Tracksperanto::Export::Base
|
4
4
|
|
5
|
+
include Tracksperanto::PFCoords
|
6
|
+
|
5
7
|
KEYFRAME_TEMPLATE = "%s %.3f %.3f %.3f"
|
6
8
|
|
7
9
|
# PFtrack wants cross-platform linebreaks
|
@@ -15,6 +17,11 @@ class Tracksperanto::Export::PFTrack4 < Tracksperanto::Export::Base
|
|
15
17
|
"PFTrack v4 .2dt file"
|
16
18
|
end
|
17
19
|
|
20
|
+
def start_export(w, h)
|
21
|
+
@width = w
|
22
|
+
@height = h
|
23
|
+
end
|
24
|
+
|
18
25
|
def start_tracker_segment(tracker_name)
|
19
26
|
# Setup for the next tracker
|
20
27
|
@frame_count = 0
|
@@ -36,7 +43,7 @@ class Tracksperanto::Export::PFTrack4 < Tracksperanto::Export::Base
|
|
36
43
|
|
37
44
|
def export_point(frame, abs_float_x, abs_float_y, float_residual)
|
38
45
|
@frame_count += 1
|
39
|
-
line = KEYFRAME_TEMPLATE % [frame, abs_float_x, abs_float_y, float_residual / 8]
|
46
|
+
line = KEYFRAME_TEMPLATE % [frame, to_pfcoord(abs_float_x), to_pfcoord(abs_float_y), float_residual / 8]
|
40
47
|
@tracker_io.write(line)
|
41
48
|
@tracker_io.write(LINEBREAK)
|
42
49
|
end
|
data/lib/import/pftrack.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# TODO: this should be rewritten as a proper state-machine parser
|
3
3
|
class Tracksperanto::Import::PFTrack < Tracksperanto::Import::Base
|
4
|
+
|
5
|
+
include Tracksperanto::PFCoords
|
6
|
+
|
4
7
|
def self.human_name
|
5
8
|
"PFTrack/PFMatchit .2dt file"
|
6
9
|
end
|
@@ -73,7 +76,7 @@ class Tracksperanto::Import::PFTrack < Tracksperanto::Import::Base
|
|
73
76
|
(1..num_of_keyframes).map do | keyframe_idx |
|
74
77
|
report_progress("Reading keyframe #{keyframe_idx} of #{num_of_keyframes} in #{t.name}")
|
75
78
|
f, x, y, residual = io.gets.chomp.split
|
76
|
-
t.keyframe!(:frame => f, :abs_x => x, :abs_y => y, :residual => residual.to_f * 8)
|
79
|
+
t.keyframe!(:frame => f, :abs_x => from_pfcoord(x), :abs_y => from_pfcoord(y), :residual => residual.to_f * 8)
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
data/lib/import/syntheyes.rb
CHANGED
@@ -20,8 +20,8 @@ class Tracksperanto::Import::Syntheyes < Tracksperanto::Import::Base
|
|
20
20
|
# Add the keyframe
|
21
21
|
k = Tracksperanto::Keyframe.new do |e|
|
22
22
|
e.frame = frame
|
23
|
-
e.abs_x = convert_from_uv(
|
24
|
-
e.abs_y = height - convert_from_uv(
|
23
|
+
e.abs_x = convert_from_uv(x, width)
|
24
|
+
e.abs_y = height - convert_from_uv(y, height) # Convert TL to BL
|
25
25
|
end
|
26
26
|
|
27
27
|
@last_tracker.push(k)
|
data/lib/pipeline/base.rb
CHANGED
@@ -31,10 +31,10 @@ module Tracksperanto::Pipeline
|
|
31
31
|
|
32
32
|
# The base pipeline is the whole process of track conversion from start to finish.
|
33
33
|
# The pipeline object organizes the import formats, scans them,
|
34
|
-
# applies the
|
34
|
+
# applies the tools. Here's how a calling sequence for a pipeline looks like:
|
35
35
|
#
|
36
36
|
# pipe = Tracksperanto::Pipeline::Base.new
|
37
|
-
# pipe.
|
37
|
+
# pipe.tool_tuples = ["Shift", {:x => 10}]
|
38
38
|
# pipe.progress_block = lambda{|percent, msg| puts("#{msg}..#{percent.to_i}%") }
|
39
39
|
# pipe.run("/tmp/shakescript.shk", :width => 720, :height => 576)
|
40
40
|
#
|
@@ -64,7 +64,7 @@ module Tracksperanto::Pipeline
|
|
64
64
|
attr_accessor :exporters
|
65
65
|
|
66
66
|
# Contains arrays of the form ["MiddewareName", {:param => value}]
|
67
|
-
attr_accessor :
|
67
|
+
attr_accessor :tool_tuples
|
68
68
|
|
69
69
|
|
70
70
|
def initialize(*any)
|
@@ -72,13 +72,13 @@ module Tracksperanto::Pipeline
|
|
72
72
|
@ios = []
|
73
73
|
end
|
74
74
|
|
75
|
-
# Will scan the
|
76
|
-
#
|
77
|
-
def
|
78
|
-
return output unless (
|
75
|
+
# Will scan the tool_tuples attribute and create a processing chain.
|
76
|
+
# Tools will be instantiated and wrap each other, starting with the first one
|
77
|
+
def wrap_output_with_tools(output)
|
78
|
+
return output unless (tool_tuples && tool_tuples.any?)
|
79
79
|
|
80
|
-
|
81
|
-
Tracksperanto.
|
80
|
+
tool_tuples.reverse.inject(output) do | wrapped, (tool_name, options) |
|
81
|
+
Tracksperanto.get_tool(tool_name).new(wrapped, options || {})
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -105,10 +105,10 @@ module Tracksperanto::Pipeline
|
|
105
105
|
mux = setup_outputs_for(from_input_file_path)
|
106
106
|
|
107
107
|
# Wrap it into a module that will prevent us from exporting invalid trackers
|
108
|
-
lint = Tracksperanto::
|
108
|
+
lint = Tracksperanto::Tool::Lint.new(mux)
|
109
109
|
|
110
|
-
# Setup
|
111
|
-
endpoint =
|
110
|
+
# Setup tools
|
111
|
+
endpoint = wrap_output_with_tools(lint)
|
112
112
|
@converted_points, @converted_keyframes = run_export(read_data, importer, endpoint)
|
113
113
|
end
|
114
114
|
|
@@ -182,7 +182,7 @@ module Tracksperanto::Pipeline
|
|
182
182
|
# Use the width and height provided by the parser itself
|
183
183
|
exporter.start_export(importer.width, importer.height)
|
184
184
|
|
185
|
-
# Now send each tracker through the
|
185
|
+
# Now send each tracker through the tool chain
|
186
186
|
obuf.each_with_index do | t, tracker_idx |
|
187
187
|
|
188
188
|
kf_weight = percent_per_tracker / t.keyframes.length
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require "forwardable"
|
3
3
|
|
4
|
-
# The base
|
5
|
-
# as an export format.
|
4
|
+
# The base tool class works just like a Tracksperanto::Export::Base, but it only wraps another exporting object and does not get registered on it's own
|
5
|
+
# as an export format. Tool can be used to massage the tracks being exported in various interesting ways - like moving the coordinates, clipping the keyframes,
|
6
6
|
# scaling the whole export or even reversing the trackers to go backwards
|
7
|
-
class Tracksperanto::
|
7
|
+
class Tracksperanto::Tool::Base
|
8
8
|
include Tracksperanto::Casts
|
9
9
|
include Tracksperanto::BlockInit
|
10
10
|
include Tracksperanto::ConstName
|
@@ -14,17 +14,17 @@ class Tracksperanto::Middleware::Base
|
|
14
14
|
extend Forwardable
|
15
15
|
def_delegators :@exporter, :start_export, :start_tracker_segment, :end_tracker_segment, :export_point, :end_export
|
16
16
|
|
17
|
-
# Used to automatically register your
|
17
|
+
# Used to automatically register your tool in Tracksperanto.tools
|
18
18
|
# Normally you wouldn't need to override this
|
19
19
|
def self.inherited(by)
|
20
|
-
Tracksperanto.
|
20
|
+
Tracksperanto.tools.push(by)
|
21
21
|
super
|
22
22
|
end
|
23
23
|
|
24
|
-
# Returns the human name of the action that the
|
24
|
+
# Returns the human name of the action that the tool will perform. The action is
|
25
25
|
# the in infinitive form, like "Remove all the invalid keyframes", "Crop the image" and so on
|
26
26
|
def self.action_description
|
27
|
-
"Base
|
27
|
+
"Base tool class"
|
28
28
|
end
|
29
29
|
|
30
30
|
# Constructor accepts the exporter that will be wrapped, followed by the optional options hash
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# Does the same as the Pad
|
3
|
-
class Tracksperanto::
|
2
|
+
# Does the same as the Pad tool but with absolute pixel values instead of fractionals
|
3
|
+
class Tracksperanto::Tool::Crop < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
parameter :top, :cast => :int, :desc => "Top crop amount in px"
|
6
6
|
parameter :left, :cast => :int, :desc => "Left crop amount in px"
|
@@ -13,7 +13,7 @@ class Tracksperanto::Middleware::Crop < Tracksperanto::Middleware::Base
|
|
13
13
|
|
14
14
|
def start_export(w, h)
|
15
15
|
left_pad, right_pad, top_pad, bottom_pad = (left / w.to_f), (right / w.to_f), (top / h.to_f), (bottom / h.to_f)
|
16
|
-
@pad = Tracksperanto::
|
16
|
+
@pad = Tracksperanto::Tool::Pad.new(@exporter, :left_pad => left_pad, :right_pad => right_pad, :top_pad => top_pad, :bottom_pad => bottom_pad)
|
17
17
|
@pad.start_export(w, h)
|
18
18
|
end
|
19
19
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Flips the comp being exported horizontally
|
3
|
-
class Tracksperanto::
|
3
|
+
class Tracksperanto::Tool::Flip < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Mirrors all the tracker paths horizontally"
|
@@ -8,7 +8,7 @@ class Tracksperanto::Middleware::Flip < Tracksperanto::Middleware::Base
|
|
8
8
|
|
9
9
|
def start_export(w, h)
|
10
10
|
factor = -1
|
11
|
-
@exporter = Tracksperanto::
|
11
|
+
@exporter = Tracksperanto::Tool::Scaler.new(@exporter, :x_factor => factor)
|
12
12
|
super
|
13
13
|
end
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Flips the comp being exported vertically
|
3
|
-
class Tracksperanto::
|
3
|
+
class Tracksperanto::Tool::Flop < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Mirror all the tracker paths vertically"
|
@@ -8,7 +8,7 @@ class Tracksperanto::Middleware::Flop < Tracksperanto::Middleware::Base
|
|
8
8
|
|
9
9
|
def start_export(w, h)
|
10
10
|
factor = -1
|
11
|
-
@exporter = Tracksperanto::
|
11
|
+
@exporter = Tracksperanto::Tool::Scaler.new(@exporter, :y_factor => factor)
|
12
12
|
super
|
13
13
|
end
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# This
|
3
|
-
class Tracksperanto::
|
2
|
+
# This tool marks all trackers as being 100% accurate
|
3
|
+
class Tracksperanto::Tool::Golden < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Reset residual of all the trackers to zero"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# This
|
2
|
+
# This tool removes trackers that contain less than min_length keyframes
|
3
3
|
# from the exported batch
|
4
|
-
class Tracksperanto::
|
4
|
+
class Tracksperanto::Tool::LengthCutoff < Tracksperanto::Tool::Base
|
5
5
|
|
6
6
|
parameter :min_length, :cast => :int, :desc => "The minimum number of keyframes for the item to contain", :default => 100
|
7
7
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
class Tracksperanto::
|
2
|
+
class Tracksperanto::Tool::LensDisto < Tracksperanto::Tool::Base
|
3
3
|
include Tracksperanto::UVCoordinates
|
4
4
|
|
5
5
|
|
@@ -58,7 +58,7 @@ class Tracksperanto::Middleware::LensDisto < Tracksperanto::Middleware::Base
|
|
58
58
|
def with_uv(x, y)
|
59
59
|
vec = Vector2.new(convert_to_uv(x, @width), convert_to_uv(y, @height))
|
60
60
|
yield(vec)
|
61
|
-
[convert_from_uv(
|
61
|
+
[convert_from_uv(vec.x, @width), convert_from_uv(vec.y, @height)]
|
62
62
|
end
|
63
63
|
|
64
64
|
# Radius is equal to aspect at the rightmost extremity
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# This
|
3
|
-
class Tracksperanto::
|
2
|
+
# This tool adds linearly interpolated keyframes BETWEEN the keyframes passing through the exporter
|
3
|
+
class Tracksperanto::Tool::Lerp < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Interpolate missing keyframes of all the trackers"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Prevents you from exporting invalid trackers
|
3
|
-
class Tracksperanto::
|
3
|
+
class Tracksperanto::Tool::Lint < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Verify all the exported trackers and check for errors"
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Sometimes your tracked sequence has been loaded from say frame 73282381, but you want to import into an application
|
3
|
-
# that expects the trackers to start at frame 1. This
|
4
|
-
class Tracksperanto::
|
3
|
+
# that expects the trackers to start at frame 1. This tool autoslips everything so that your trackers start at frame 1.
|
4
|
+
class Tracksperanto::Tool::MoveToFirst < Tracksperanto::Tool::Base
|
5
5
|
|
6
6
|
def self.action_description
|
7
|
-
"Move all the keyframes in time so that the
|
7
|
+
"Move all the keyframes in time so that the track starts at frame 1"
|
8
8
|
end
|
9
9
|
|
10
10
|
def start_export(width, height)
|