-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhomography.rb
39 lines (38 loc) · 933 Bytes
/
homography.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
require 'matrix'
require 'linalg'
include Linalg
class Matrix
def to_dmatrix
DMatrix[*to_a]
end
def svd
to_dmatrix.svd.collect { |m| m.to_matrix }
end
end
class Vector
def reshape(w, h)
Matrix[*(0 ... h).collect { |i| to_a[i * w ... i.succ * w] }]
end
end
class DMatrix
def to_matrix
Matrix[*to_a]
end
end
class Homography
def initialize(*pairs)
constraints = []
pairs.each do |p,ps|
constraints.push [p[0].to_f, p[1].to_f, 1.0, 0.0, 0.0, 0.0,
-ps[0].to_f * p[0].to_f, -ps[0].to_f * p[1].to_f, -ps[0].to_f]
constraints.push [0.0, 0.0, 0.0, p[0].to_f, p[1].to_f, 1.0,
-ps[1].to_f * p[0].to_f, -ps[1].to_f * p[1].to_f, -ps[1].to_f]
end
@matrix = Matrix[*constraints].svd[2].row(8).reshape 3, 3
end
def transform(x, y)
p = Vector[x.to_f, y.to_f, 1.0]
ps = @matrix * p
[ps[0] / ps[2], ps[1] / ps[2]]
end
end