From ed2f10b265485040197402bbd5dbe0dd6058cb11 Mon Sep 17 00:00:00 2001 From: Tomas Musil Date: Sun, 6 Jul 2014 00:25:52 +0200 Subject: [PATCH 1/1] preliminary work on generalized RANSAC --- src/gridf3.py | 18 ++++++++++++++++-- src/imago.py | 4 ++++ src/ransac.py | 33 +++++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/gridf3.py b/src/gridf3.py index 0697b92..693b8ee 100644 --- a/src/gridf3.py +++ b/src/gridf3.py @@ -12,6 +12,9 @@ from geometry import l2ad class GridFittingFailedError(Exception): pass +class BadGenError(Exception): + pass + def plot_line(line, c, size): points = linef.line_from_angl_dist(line, size) pyplot.plot(*zip(*points), color=c) @@ -32,12 +35,16 @@ class Diagonal_model: if l1[i] and l2[j]: yield (l1[i], l2[j]) + def remove(self, data): + self.data = list(set(self.data) - set(data)) + def initial(self): try: - return self.gen.next() + nxt = self.gen.next() except StopIteration: self.gen = self.initial_g() - return self.gen.next() + nxt = self.gen.next() + return nxt def get(self, sample): if len(sample) == 2: @@ -50,11 +57,18 @@ class Diagonal_model: score = 0 a, b, c = est dst = lambda (x, y): abs(a * x + b * y + c) / sqrt(a*a+b*b) + l1 = None + l2 = None for p in self.data: d = dst(p) if d <= dist: cons.append(p) + if p.l1 == l1 or p.l2 == l2: + return float("inf"), [] + else: + l1, l2 = p.l1, p.l2 score += min(d, dist) + return score, cons def intersection((a1, b1, c1), (a2, b2, c2)): diff --git a/src/imago.py b/src/imago.py index b513253..b87da99 100755 --- a/src/imago.py +++ b/src/imago.py @@ -108,6 +108,10 @@ def main(): d_file.close() else: lines, l1, l2, bounds, hough = linef.find_lines(image, do_something, logger) + #d_file = open('lines09.pickle', 'wb') + #pickle.dump(lines, d_file) + #d_file.close() #TODO delete this + grid, lines = gridf.find(lines, image.size, l1, l2, bounds, hough, show_all, do_something, logger) diff --git a/src/ransac.py b/src/ransac.py index 4908421..cc16d2f 100644 --- a/src/ransac.py +++ b/src/ransac.py @@ -52,18 +52,20 @@ def iterate(model, distance): score = float("inf") consensual = model.initial() estimate = model.get(consensual) - new_score, consensual = model.score(estimate, distance) - while (new_score < score): - score = new_score - try: - estimate = model.get(consensual) - new_score, consensual = model.score(estimate, distance) - except NP.linalg.LinAlgError: - pass + new_score, new_consensual = model.score(estimate, distance) + if new_consensual != []: + while (new_score < score): + score, consensual = new_score, new_consensual + try: + estimate = model.get(consensual) + new_score, new_consensual = model.score(estimate, distance) + except (NP.linalg.LinAlgError): + pass return score, estimate, consensual -def estimate(data, dist, k, modelClass=Linear_model): - model = modelClass(data) +def estimate(data, dist, k, modelClass=Linear_model, model=None): + if not model: + model = modelClass(data) best = float("inf") estimate = None consensual = None @@ -82,3 +84,14 @@ def ransac_duo(data, dist, k, mk, modelClass=Linear_model): model, cons = estimate(set(data) - set(cons), dist, k, modelClass) return (model, cons), estimate(set(data) - set(cons), dist, k, modelClass) +def ransac_multi(m, data, dist, k, modelClass=Linear_model, model=None): + ests = [] + cons = [] + for i in xrange(m): + est, cons_new = estimate(None, dist, k, model=model) + model.remove(cons_new) + ests.append(est) + return ests + + + -- 2.4.2