ce50be7549d33e65822cbf49052965b470bf3c2e
[imago.git] / src / gridf2.py
1 from math import sqrt
2 import random
3 import sys
4
5 import linef as linef
6 import gridf as gridf
7 from manual import lines as g_grid
8 from geometry import l2ad
9 import new_geometry as gm
10
11
12 def plot_line(line, c):
13     points = linef.line_from_angl_dist(line, (520, 390))
14     pyplot.plot(*zip(*points), color=c)
15
16 def dst((x, y), (a, b, c)):
17     return abs(a * x + b * y + c) / sqrt(a*a+b*b)
18
19 def points_to_line((x1, y1), (x2, y2)):
20     return (y2 - y1, x1 - x2, x2 * y1 - x1 * y2)
21
22 def to_general(line):
23     points = linef.line_from_angl_dist(line, (520, 390))
24     return points_to_line(*points)
25
26 def nearest(lines, point):
27     return min(map(lambda l: dst(point, l), lines))
28
29 def nearest2(lines, point):
30     return min(map(lambda l: dst(point, points_to_line(*l)), lines))
31
32 size = (520, 390)
33
34 def generate_models(sgrid, lh):
35     for f in [0, 1, 2, 3, 5, 7, 8, 11, 15, 17]:
36         grid = gm.fill(sgrid[0], sgrid[1], lh , f)
37         grid = [sgrid[0]] + grid + [sgrid[1]]
38         for s in xrange(17 - f):
39             grid = [gm.expand_left(grid, lh)] + grid
40         yield grid
41         for i in xrange(17 - f):
42             grid = grid[1:]
43             grid.append(gm.expand_right(grid, lh))
44             yield grid
45
46 def score(grid, lines, limit):
47     dst = lambda (a, b, c): (a * 260 + b * 195 + c) / sqrt(a*a+b*b)
48     dsg = lambda l: dst(points_to_line(*l))
49     ds = map(dsg, grid)
50     d = max(map(abs, ds))
51     if d > limit:
52         return 999999
53     score = 0
54     for line in lines:
55         s = min(map(lambda g: abs(line[1] - g), ds))
56         s = min(s, 2)
57         score += s
58
59     return score
60
61 def lines2grid(lines, perp_l):
62     b1, b2 = perp_l[0], perp_l[-1]
63     f = lambda l: (gm.intersection(b1, l), gm.intersection(b2, l))
64     return map(f, lines)
65
66 def test(): 
67     import pickle
68     import matplotlib.pyplot as pyplot
69     import time
70
71     points = pickle.load(open('edges.pickle'))
72
73     lines = pickle.load(open('lines.pickle'))
74
75     r_lines = pickle.load(open('r_lines.pickle'))
76
77     #pyplot.scatter(*zip(*sum(r_lines, [])))
78     #pyplot.show()
79
80     l1, l2 = lines
81
82     lines_general = map(to_general, sum(lines, []))
83     near_points = [p for p in points if nearest(lines_general, p) <= 2]
84
85     while True:
86         t0 = time.time()
87         sc1, gridv = 999999, None
88         for i in range(250):
89             l1s = random.sample(l1, 2)
90             l1s.sort(key=lambda l: l[1])
91             sgrid = map(lambda l:linef.line_from_angl_dist(l, size), l1s) 
92             middle = lambda m: ((m, 0),(m, 390))
93             middle = middle(gm.intersection((sgrid[0][0], sgrid[1][1]), 
94                                             (sgrid[0][1], sgrid[1][0]))[0])
95             lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
96             sc1_n, gridv_n = min(map(lambda g: (score(g, l1, 210), g), generate_models(sgrid, lh)))
97             if sc1_n < sc1:
98                 sc1, gridv = sc1_n, gridv_n
99
100         sc2, gridh = 999999, None
101         for i in range(250):
102             l2s = random.sample(l2, 2)
103             l2s.sort(key=lambda l: l[1])
104             sgrid = map(lambda l:linef.line_from_angl_dist(l, size), l2s) 
105             middle = lambda m: ((0, m),(520, m))
106             middle = middle(gm.intersection((sgrid[0][0], sgrid[1][1]), 
107                                             (sgrid[0][1], sgrid[1][0]))[1])
108             lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
109             sc2_n, gridh_n = min(map(lambda g: (score(g, l2, 275), g), generate_models(sgrid, lh)))
110             if sc2_n < sc2:
111                 sc2, gridh = sc2_n, gridh_n
112         gridv, gridh = lines2grid(gridv, gridh), lines2grid(gridh, gridv)
113         print time.time() - t0
114         print sc1, sc2
115
116         pyplot.scatter(*zip(*near_points))
117
118         #map(lambda l: plot_line(l, 'g'), l1 + l2)
119         map(lambda l: pyplot.plot(*zip(*l), color='g'), gridv)
120         map(lambda l: pyplot.plot(*zip(*l), color='g'), gridh)
121         #plot_line(l2s[0], 'r')
122         #plot_line(l2s[1], 'r')
123         #plot_line(l1s[0], 'r')
124         #plot_line(l1s[1], 'r')
125         pyplot.xlim(0, 520)
126         pyplot.ylim(0, 390)
127         pyplot.show()
128
129 def find(lines, size, l1, l2, bounds, hough, show_all, do_something, logger):
130     logger("finding the grid")
131     l1, l2 = lines
132     sc1, gridv = 999999, None
133     for i in range(250):
134         l1s = random.sample(l1, 2)
135         l1s.sort(key=lambda l: l[1])
136         sgrid = map(lambda l:linef.line_from_angl_dist(l, size), l1s) 
137         middle = lambda m: ((m, 0),(m, 390))
138         middle = middle(gm.intersection((sgrid[0][0], sgrid[1][1]), 
139                                         (sgrid[0][1], sgrid[1][0]))[0])
140         lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
141         sc1_n, gridv_n = min(map(lambda g: (score(g, l1, 210), g), generate_models(sgrid, lh)))
142         if sc1_n < sc1:
143             sc1, gridv = sc1_n, gridv_n
144
145     sc2, gridh = 999999, None
146     for i in range(250):
147         l2s = random.sample(l2, 2)
148         l2s.sort(key=lambda l: l[1])
149         sgrid = map(lambda l:linef.line_from_angl_dist(l, size), l2s) 
150         middle = lambda m: ((0, m),(520, m))
151         middle = middle(gm.intersection((sgrid[0][0], sgrid[1][1]), 
152                                         (sgrid[0][1], sgrid[1][0]))[1])
153         lh = (gm.intersection(sgrid[0], middle), gm.intersection(sgrid[1], middle))
154         sc2_n, gridh_n = min(map(lambda g: (score(g, l2, 275), g), generate_models(sgrid, lh)))
155         if sc2_n < sc2:
156             sc2, gridh = sc2_n, gridh_n
157     gridv, gridh = lines2grid(gridv, gridh), lines2grid(gridh, gridv)
158
159     grid = [gridv, gridh]
160     grid_lines = [[l2ad(l, size) for l in grid[0]], 
161                   [l2ad(l, size) for l in grid[1]]]
162
163     return grid, grid_lines