class Tracksperanto::Tool::LensDisto

Constants

STEPS

Public Class Methods

action_description() click to toggle source
# File lib/tools/lens_disto.rb, line 11
def self.action_description
  "Apply or remove lens distortion with the Syntheyes algorithm"
end

Public Instance Methods

export_point(frame, float_x, float_y, float_residual) click to toggle source
Calls superclass method
# File lib/tools/lens_disto.rb, line 23
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
start_export(w, h) click to toggle source
Calls superclass method
# File lib/tools/lens_disto.rb, line 15
def start_export(w, h)
  @width, @height = w, h
  @aspect = @width.to_f / @height
  
  generate_lut
  super
end

Private Instance Methods

disto(x, y) click to toggle source
# File lib/tools/lens_disto.rb, line 68
def disto(x, y)
  with_uv(x, y) do | pt |
    # Find the good tuples to interpolate on
    f = disto_interpolated(get_radius(pt))
    pt.x = pt.x * f
    pt.y = pt.y * f
  end
end
disto_interpolated(r) click to toggle source
# File lib/tools/lens_disto.rb, line 92
def disto_interpolated(r)
  left , right = nil, nil
  @lut.each_with_index do | rf, i |
    if rf.r > r
      right = rf
      left = @lut[i -1]
      return lerp(r, left.r, right.r, left.f, right.f)
    end
  end
end
distort_radius(r) click to toggle source

Radius is equal to aspect at the rightmost extremity

# File lib/tools/lens_disto.rb, line 64
def distort_radius(r)
  1 + (r*r*(k + kcube * r))
end
generate_lut() click to toggle source

We apply disto using a lookup table of y = f®

# File lib/tools/lens_disto.rb, line 44
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, distort_radius(r)))
  end
end
get_radius(pt) click to toggle source
# File lib/tools/lens_disto.rb, line 77
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
lerp(x, left_x, right_x, left_y, right_y) click to toggle source
# File lib/tools/lens_disto.rb, line 114
def lerp(x, left_x, right_x, left_y, right_y)
  dx = right_x - left_x
  dy = right_y - left_y
  t = (x - left_x) / dx
  left_y + (dy * t)
end
undisto(x, y) click to toggle source
# File lib/tools/lens_disto.rb, line 83
def undisto(x, y)
  with_uv(x, y) do | pt |
    # Find the good tuples to interpolate on
    f = undisto_interpolated(get_radius(pt))
    pt.x = pt.x / f
    pt.y = pt.y / f
  end
end
undisto_interpolated(r) click to toggle source
# File lib/tools/lens_disto.rb, line 103
def undisto_interpolated(r)
  left , right = nil, nil
  @lut.each_with_index do | xf, i |
    if xf.m > r
      right = xf
      left = @lut[i -1]
      return lerp(r, left.m, right.m, left.f, right.f)
    end
  end
end
with_uv(x, y) { |vec| ... } click to toggle source
# File lib/tools/lens_disto.rb, line 57
def with_uv(x, y)
  vec = Vector2.new(convert_to_uv(x, @width), convert_to_uv(y, @height))
  yield(vec)
  [convert_from_uv(vec.x, @width), convert_from_uv(vec.y, @height)]
end