fix bug in intrsc
authorTomas Musil <tomik.musil@gmail.com>
Wed, 2 Jul 2014 02:48:57 +0000 (04:48 +0200)
committerTomas Musil <tomik.musil@gmail.com>
Wed, 2 Jul 2014 02:53:20 +0000 (04:53 +0200)
src/gridf2.py
src/intrsc.py

index 8e6936a..0d9246f 100644 (file)
@@ -55,7 +55,7 @@ def score(grid, lines, limit):
     score = 0
     for line in lines:
         s = min(map(lambda g: abs(line[1] - g), ds))
-        s = min(s, 2)
+        s = min(s, 4)
         score += s
 
     return score
@@ -65,6 +65,28 @@ def lines2grid(lines, perp_l):
     f = lambda l: (gm.intersection(b1, l), gm.intersection(b2, l))
     return map(f, lines)
 
+def pertubations(grid, middle_l):
+    corners = [grid[0], grid[-1]]
+    for l in [0, 1]:
+        for c in [0, 1]:
+            for s in [0, 1]:
+                for x in [-1, 1]:
+                    sgrid = corners
+                    sgrid[l] = list(sgrid[l])
+                    sgrid[l][c] = list(sgrid[l][c])
+                    sgrid[l][c][s] += x
+                    try:
+                        middle = middle_l(sgrid)
+                        lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
+                        sgrid = ([sgrid[0]] +
+                             gm.fill(sgrid[0], sgrid[1], lh, 17) +
+                             [sgrid[1]])
+                    except ZeroDivisionError:
+                        continue
+
+                    yield sgrid
+
+
 def test(): 
     import pickle
     import matplotlib.pyplot as pyplot
@@ -88,31 +110,58 @@ def test():
     while True:
         t0 = time.time()
         sc1, gridv = 999999, None
-        for i in range(250):
-            l1s = random.sample(l1, 2)
-            l1s.sort(key=lambda l: l[1])
-            sgrid = map(lambda l:linef.line_from_angl_dist(l, size), l1s) 
-            middle = lambda m: ((m, 0),(m, 390))
-            middle = middle(gm.intersection((sgrid[0][0], sgrid[1][1]), 
-                                            (sgrid[0][1], sgrid[1][0]))[0])
-            lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
-            sc1_n, gridv_n = min(map(lambda g: (score(g, l1, 210), g), generate_models(sgrid, lh)))
-            if sc1_n < sc1:
-                sc1, gridv = sc1_n, gridv_n
-
         sc2, gridh = 999999, None
-        for i in range(250):
-            l2s = random.sample(l2, 2)
-            l2s.sort(key=lambda l: l[1])
-            sgrid = map(lambda l:linef.line_from_angl_dist(l, size), l2s) 
-            middle = lambda m: ((0, m),(520, m))
-            middle = middle(gm.intersection((sgrid[0][0], sgrid[1][1]), 
-                                            (sgrid[0][1], sgrid[1][0]))[1])
-            lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
-            sc2_n, gridh_n = min(map(lambda g: (score(g, l2, 275), g), generate_models(sgrid, lh)))
-            if sc2_n < sc2:
-                sc2, gridh = sc2_n, gridh_n
-        gridv, gridh = lines2grid(gridv, gridh), lines2grid(gridh, gridv)
+        sc1_n, sc2_n = 999999, 999999
+        gridv_n, gridh_n = None, None
+        for k in range(50):
+            for i in range(5):
+                l1s = random.sample(l1, 2)
+                l1s.sort(key=lambda l: l[1])
+                sgrid = map(lambda l:linef.line_from_angl_dist(l, size), l1s)
+                middle_l1 = lambda m: ((m, 0),(m, 390))
+                middle_l = lambda sgrid: middle_l1(gm.intersection((sgrid[0][0], sgrid[1][1]), 
+                                                (sgrid[0][1], sgrid[1][0]))[0])
+                middle = middle_l(sgrid)
+                lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
+                sc1_n, gridv_n = min(map(lambda g: (score(g, l1, 210), g), generate_models(sgrid, lh)))
+
+                p = True
+                while p:
+                    p = False
+                    for ng in pertubations(gridv_n, middle_l): # TODO randomize
+                        sc = score(ng, l1, 210)
+                        if sc < sc1_n:
+                            sc1_n, gridv_n = sc, ng
+                            p = True
+
+                if sc1_n < sc1:
+                    sc1, gridv = sc1_n, gridv_n
+
+            for i in range(5):
+                l2s = random.sample(l2, 2)
+                l2s.sort(key=lambda l: l[1])
+                sgrid = map(lambda l:linef.line_from_angl_dist(l, size), l2s) 
+                middle_l1 = lambda m: ((0, m),(520, m))
+                middle_l = lambda sgrid: middle_l1(gm.intersection((sgrid[0][0], sgrid[1][1]), 
+                                                (sgrid[0][1], sgrid[1][0]))[1])
+                middle = middle_l(sgrid)
+                lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
+                sc2_n, gridh_n = min(map(lambda g: (score(g, l2, 275), g), generate_models(sgrid, lh)))
+
+                p = True
+                while p:
+                    p = False
+                    for ng in pertubations(gridh_n, middle_l): # TODO randomize
+                        sc = score(ng, l2, 275)
+                        if sc < sc2_n:
+                            sc2_n, gridh = sc, ng
+                            p = True
+
+                if sc2_n < sc2:
+                    sc2, gridh = sc2_n, gridh_n
+
+            gridv, gridh = lines2grid(gridv, gridh), lines2grid(gridh, gridv)
+
         print time.time() - t0
         print sc1, sc2
 
index a740212..cbf922a 100644 (file)
@@ -8,6 +8,7 @@ import ImageDraw
 import filters
 import k_means
 import output
+import linef
 
 def dst(line):
     """Return normalized line."""
@@ -115,20 +116,28 @@ def mean_luma(cluster):
     """Return mean luma of the *cluster* of points."""
     return sum(c[0][0] for c in cluster) / float(len(cluster))
 
+def to_general(line, size):
+    # TODO comment
+    (x1, y1), (x2, y2) = linef.line_from_angl_dist(line, size)
+    return (y2 - y1, x1 - x2, x2 * y1 - x1 * y2)
+
+def intersection(l1, l2):
+    a1, b1, c1 = l1
+    a2, b2, c2 = l2
+    delim = float(a1 * b2 - b1 * a2)
+    x = (b1 * c2 - c1 * b2) / delim
+    y = (c1 * a2 - a1 * c2) / delim
+    return x, y
+
 def intersections_from_angl_dist(lines, size, get_all=True):
     """Take grid-lines and size of the image. Return intersections."""
+    lines1 = map(lambda l: to_general(l, size), lines[1])
+    lines0 = map(lambda l: to_general(l, size), lines[0])
     intersections = []
-    for (angl1, dist1) in lines[1]:
+    for l1 in lines1:
         line = []
-        for (angl2, dist2) in lines[0]:
-            if abs(angl1 - angl2) > 0.4:
-                i_x =  (- ((dist2 / cos(angl2)) - (dist1 / cos(angl1))) 
-                        / (tan(angl1) - tan(angl2)))
-                i_y = (tan(angl1) * i_x) - (dist1 / cos(angl1))
-                if get_all or (-size[0] / 2 < i_x < size[0] / 2 and 
-                    -size[1] / 2 < i_y < size[1] / 2):
-                    line.append((int(i_x + size[0] / 2),
-                                 int(i_y + size[1] / 2)))
+        for l2 in lines0:
+            line.append(intersection(l1, l2))
         intersections.append(line)
     return intersections