work on the third variant of gridf
authorTomas Musil <tomik.musil@gmail.com>
Wed, 2 Jul 2014 07:10:28 +0000 (09:10 +0200)
committerTomas Musil <tomik.musil@gmail.com>
Wed, 2 Jul 2014 07:10:28 +0000 (09:10 +0200)
gridf3.py [new file with mode: 0644]
src/ransac.py

diff --git a/gridf3.py b/gridf3.py
new file mode 100644 (file)
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()
+
+
index 197fc31..69d6177 100644 (file)
@@ -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)