From: Tomas Musil Date: Wed, 2 Jul 2014 07:10:28 +0000 (+0200) Subject: work on the third variant of gridf X-Git-Url: http://git.tomasm.cz/imago.git/commitdiff_plain/0839e3f3e8d51118585f10e19ab9ed8f96c36360 work on the third variant of gridf --- diff --git a/gridf3.py b/gridf3.py new file mode 100644 index 0000000..9e87881 --- /dev/null +++ b/gridf3.py @@ -0,0 +1,78 @@ +import pickle +import matplotlib.pyplot as pyplot +import random + +lines = pickle.load(open('lines.pickle')) + +from src.intrsc import intersections_from_angl_dist +import src.linef as linef +import src.ransac as ransac + +points = intersections_from_angl_dist(lines, (520, 390)) + +pyplot.scatter(*zip(*sum(points, []))) + +def plot_line(line, c): + points = linef.line_from_angl_dist(line, (520, 390)) + pyplot.plot(*zip(*points), color=c) + +def plot_line_g((a, b, c), max_x): + find_y = lambda x: - (c + a * x) / b + pyplot.plot([0, max_x], [find_y(0), find_y(max_x)], color='b') + +class Diagonal_model: + def __init__(self, data): + self.data = [p for p in sum(data, []) if p] + self.lines = data + self.gen = self.initial_g() + + def initial_g(self): + l1, l2 = random.sample(self.lines, 2) + for i in xrange(len(l1)): + for j in xrange(len(l2)): + if i == j: + continue + if l1[i] and l2[j]: + yield (l1[i], l2[j]) + + def initial(self): + try: + return self.gen.next() + except StopIteration: + self.gen = self.initial_g() + return self.gen.next() + + def get(self, sample): + if len(sample) == 2: + return ransac.points_to_line(*sample) + else: + return ransac.least_squares(sample) + +def intersection((a1, b1, c1), (a2, b2, c2)): + delim = float(a1 * b2 - b1 * a2) + x = (b1 * c2 - c1 * b2) / delim + y = (c1 * a2 - a1 * c2) / delim + return x, y + + + +while True: + line1, cons = ransac.estimate(points, 2, 800, Diagonal_model) + points2 = map(lambda l: [(p if not p in cons else None) for p in l], points) + line2, cons2 = ransac.estimate(points2, 2, 800, Diagonal_model) + center = intersection(line1, line2) + + + plot_line_g(line1, 520) + plot_line_g(line2, 520) + pyplot.scatter(*zip(*sum(points, []))) + pyplot.scatter([center[0]], [center[1]], color='r') + pyplot.xlim(0, 520) + pyplot.ylim(0, 390) + pyplot.show() + +#map(lambda l: plot_line(l, 'g'), sum(lines, [])) + +pyplot.show() + + diff --git a/src/ransac.py b/src/ransac.py index 197fc31..69d6177 100644 --- a/src/ransac.py +++ b/src/ransac.py @@ -7,8 +7,6 @@ import numpy as NP # TODO comments # TODO threshold -def initial_estimate(data): - return random.sample(data, 2) def points_to_line((x1, y1), (x2, y2)): return (y2 - y1, x1 - x2, x2 * y1 - x1 * y2) @@ -26,37 +24,49 @@ def least_squares(data): [a,c] = NP.dot(NP.linalg.inv(NP.dot(xt, x)), xt).dot(y).flat return (a, -1, c) -def get_model(data): - if len(data) == 2: - return points_to_line(*data) - else: - return least_squares(data) +class Linear_model: + def __init__(self, data): + self.data = data -def iterate(data, distance): + def get(self, sample): + if len(sample) == 2: + return points_to_line(*sample) + else: + return least_squares(sample) + + def initial(self): + return random.sample(self.data, 2) + +def iterate(model, distance): consensus = 0 - consensual = initial_estimate(data) + consensual = model.initial() while (len(consensual) > consensus): consensus = len(consensual) - model = get_model(consensual) - consensual = filter_near(data, model, distance) - return consensus, model, consensual + try: + estimate = model.get(consensual) + except NP.linalg.LinAlgError: + pass + consensual = filter_near(model.data, estimate, distance) + return consensus, estimate, consensual -def estimate(data, dist, k): +def estimate(data, dist, k, modelClass=Linear_model): + model = modelClass(data) best = 0 - model = None + estimate = None consensual = None for i in xrange(0, k): - new, new_model, new_consensual = iterate(data, dist) + new, new_estimate, new_consensual = iterate(model, dist) if new > best: best = new - model = new_model + estimate = new_estimate consensual = new_consensual - return model, consensual + return estimate, consensual -def ransac_duo(data, dist, k, mk): +def ransac_duo(data, dist, k, mk, modelClass=Linear_model): cons = [] for i in xrange(mk): - model, cons = estimate(set(data) - set(cons), dist, k) - return (model, cons), estimate(set(data) - set(cons), dist, k) + print data, cons + model, cons = estimate(set(data) - set(cons), dist, k, modelClass) + return (model, cons), estimate(set(data) - set(cons), dist, k, modelClass)