1 """RANSAC estimation."""
11 def points_to_line((x1, y1), (x2, y2)):
12 return (y2 - y1, x1 - x2, x2 * y1 - x1 * y2)
14 def filter_near(data, line, distance):
16 dst = lambda (x, y): abs(a * x + b * y + c) / sqrt(a*a+b*b)
17 is_near = lambda p: dst(p) <= distance
18 return [p for p in data if is_near(p)]
20 def least_squares(data):
21 x = NP.matrix([(a, 1) for (a, b) in data])
23 y = NP.matrix([[b] for (a, b) in data])
24 [a,c] = NP.dot(NP.linalg.inv(NP.dot(xt, x)), xt).dot(y).flat
28 def __init__(self, data):
31 def get(self, sample):
33 return points_to_line(*sample)
35 return least_squares(sample)
38 return random.sample(self.data, 2)
40 def iterate(model, distance):
42 consensual = model.initial()
43 while (len(consensual) > consensus):
44 consensus = len(consensual)
46 estimate = model.get(consensual)
47 except NP.linalg.LinAlgError:
49 consensual = filter_near(model.data, estimate, distance)
50 return consensus, estimate, consensual
52 def estimate(data, dist, k, modelClass=Linear_model):
53 model = modelClass(data)
57 for i in xrange(0, k):
58 new, new_estimate, new_consensual = iterate(model, dist)
61 estimate = new_estimate
62 consensual = new_consensual
64 return estimate, consensual
66 def ransac_duo(data, dist, k, mk, modelClass=Linear_model):
70 model, cons = estimate(set(data) - set(cons), dist, k, modelClass)
71 return (model, cons), estimate(set(data) - set(cons), dist, k, modelClass)