1 """RANSAC estimation."""
10 def points_to_line((x1, y1), (x2, y2)):
11 return (y2 - y1, x1 - x2, x2 * y1 - x1 * y2)
13 def filter_near(data, line, distance):
15 dst = lambda (x, y): abs(a * x + b * y + c) / sqrt(a*a+b*b)
16 is_near = lambda p: dst(p) <= distance
17 return [p for p in data if is_near(p)]
19 def least_squares(data):
20 x = NP.matrix([(a, 1) for (a, b) in data])
22 y = NP.matrix([[b] for (a, b) in data])
23 [a,c] = NP.dot(NP.linalg.inv(NP.dot(xt, x)), xt).dot(y).flat
27 def __init__(self, data):
30 def get(self, sample):
32 return points_to_line(*sample)
34 return least_squares(sample)
37 return random.sample(self.data, 2)
39 def score(self, est, dist):
43 dst = lambda (x, y): abs(a * x + b * y + c) / sqrt(a*a+b*b)
51 def remove(self, data):
52 self.data = list(set(self.data) - set(data))
54 def iterate(model, distance):
56 consensual = model.initial()
57 estimate = model.get(consensual)
58 new_score, new_consensual = model.score(estimate, distance)
59 if new_consensual != []:
60 while (new_score < score):
61 score, consensual = new_score, new_consensual
63 estimate = model.get(consensual)
64 new_score, new_consensual = model.score(estimate, distance)
65 except (NP.linalg.LinAlgError):
67 return score, estimate, consensual
69 def estimate(data, dist, k, modelClass=Linear_model, model=None):
71 model = modelClass(data)
75 for i in xrange(0, k):
76 new, new_estimate, new_consensual = iterate(model, dist)
79 estimate = new_estimate
80 consensual = new_consensual
82 return estimate, consensual
84 def ransac_multi(m, data, dist, k, modelClass=Linear_model, model=None):
86 model = modelClass(data)
90 est, cons_new = estimate(None, dist, k, model=model)
91 model.remove(cons_new)
92 ests.append((est, cons_new))