lib/middleware/lens_disto.rb in tracksperanto-2.9.9 vs lib/middleware/lens_disto.rb in tracksperanto-2.10.0

- old
+ new

@@ -1,22 +1,10 @@ # -*- encoding : utf-8 -*- class Tracksperanto::Middleware::LensDisto < Tracksperanto::Middleware::Base include Tracksperanto::UVCoordinates + - class Vector2 < Struct.new(:x, :y) - end - - class RF < Struct.new(:r, :f) - def inspect - '(%0.3f %0.3f)' % [r, f] - end - - def m - r * f - end - end - parameter :k, :cast => :float, :desc => "Quartic distortion coefficient", :default => 0 parameter :kcube, :cast => :float, :desc => "Cubic distortion coefficient", :default => 0 parameter :remove, :cast => :bool, :desc => "Remove distortion instead of adding it" STEPS = 256 @@ -27,72 +15,77 @@ def start_export(w, h) @width, @height = w, h @aspect = @width.to_f / @height + generate_lut + super + end + + def export_point(frame, float_x, float_y, float_residual) + x, y = remove ? undisto(float_x, float_y) : disto(float_x, float_y) + super(frame, x, y, float_residual) + end + + private + + class Vector2 < Struct.new(:x, :y) + end + + class RF < Struct.new(:r, :f) + def inspect + '(%0.3f %0.3f)' % [r, f] + end + + def m + r * f + end + end + + # We apply disto using a lookup table of y = f(r) + def generate_lut # Generate the lookup table @lut = [RF.new(0.0, 1.0)] max_r = @aspect + 1 increment = max_r / STEPS r = 0 STEPS.times do | mult | r += increment - @lut.push(RF.new(r, disto_radius(r))) + @lut.push(RF.new(r, distort_radius(r))) end - - @lut.inspect - super end - def export_point(frame, float_x, float_y, float_residual) - x, y = remove ? undisto(float_x, float_y) : disto(float_x, float_y) - super(frame, x, y, float_residual) - end - - private - def with_uv(x, y) vec = Vector2.new(convert_to_uv(x, @width), convert_to_uv(y, @height)) yield(vec) [convert_from_uv(@width, vec.x), convert_from_uv(@height, vec.y)] end # Radius is equal to aspect at the rightmost extremity - def disto_radius(r) - r2 = r ** 2 - # Skipping the square root speeds things up if we don't need it - f = if kcube.abs > 0.00001 - 1 + (r2 * (k + kcube * Math.sqrt(r2))); - else - 1 + (r2 * k); - end + def distort_radius(r) + 1 + (r*r*(k + kcube * r)) end def disto(x, y) with_uv(x, y) do | pt | - # Get the radius of the point - x = pt.x * @aspect - r = Math.sqrt(x.abs**2 + pt.y.abs**2) - # Find the good tuples to interpolate on - f = disto_interpolated(r) - + f = disto_interpolated(get_radius(pt)) pt.x = pt.x * f pt.y = pt.y * f end end + def get_radius(pt) + # Get the radius of the point + x = pt.x * @aspect + r = Math.sqrt(x.abs**2 + pt.y.abs**2) + end def undisto(x, y) with_uv(x, y) do | pt | - # Get the radius of the point - x = pt.x * @aspect - r = Math.sqrt(x.abs**2 + pt.y.abs**2) - # Find the good tuples to interpolate on - f = undisto_interpolated(r) - + f = undisto_interpolated(get_radius(pt)) pt.x = pt.x / f pt.y = pt.y / f end end