13702b0736652d52ceeeb8736bee1f0cbd812e2e
[imago.git] / imago.py
1 #!/usr/bin/env python
2
3 """Usage:
4 imago.py file
5     analyses the given file
6 imago.py file --debug
7     shows every step of the computation
8 imago.py --help
9     shows this help
10
11 """
12
13 import sys
14 import math
15
16 try:
17     import Image, ImageDraw
18 except ImportError, msg:
19     print >>sys.stderr, msg
20     sys.exit(1)
21
22 import im_debug
23 import filters
24 from hough import Hough
25
26 class UsageError(Exception):
27     def __init__(self, msg):
28         self.msg = msg
29
30 def main(*argv):
31     """Main function of the program."""
32     
33     show_all = False
34
35     try:
36         if argv is ():
37             argv = sys.argv[1:]
38             if argv == []:
39                 raise UsageError('Missing filename')
40         if "--help" in argv:
41             print __doc__
42             return 0
43         if "--debug" in argv:
44             show_all = True
45     except UsageError, err:
46         print >>sys.stderr, err.msg, "(\"imago.py --help\" for help)"
47         return 2
48
49     try:
50         image = Image.open(argv[0])
51     except IOError, msg:
52         print >>sys.stderr, msg
53         return 1
54     if show_all:
55         im_debug.show(image, "original image")
56
57     im_l = image.convert('L')
58     if show_all:
59         im_debug.show(im_l, "ITU-R 601-2 luma transform")
60
61     im_edges = filters.edge_detection(im_l)
62     if show_all:    
63         im_debug.show(im_edges, "edge detection")
64
65     im_h = filters.high_pass(im_edges, 100)
66     if show_all:
67         im_debug.show(im_h, "high pass filters")
68     
69     hough1 = Hough(im_h.size)
70     im_hough = hough1.transform(im_h)
71     if show_all:
72         im_debug.show(im_hough, "hough transform")
73
74     im_h2 = filters.high_pass(im_hough, 120)
75     if show_all:
76         im_debug.show(im_h2, "second high pass filters")
77
78     hough2 = Hough(im_h2.size)
79     im_hough2 = hough2.transform(im_h2)
80     if show_all:
81         im_debug.show(im_hough2, "second hough transform")
82
83     im_h3 = filters.high_pass(im_hough2, 120)
84     if show_all:
85         im_debug.show(im_h3, "third high pass filters")
86      
87     lines = hough2.find_angle_distance(im_h3)
88
89     im_lines = Image.new('L', im_h2.size)
90
91     draw = ImageDraw.Draw(im_lines)
92
93     for line in lines:
94         draw.line(line_from_angl_dist(line, im_h2.size), fill=255)
95     if show_all:
96         im_debug.show(im_lines, "lines")
97
98     im_c = combine(im_h2, im_lines)
99     if show_all:
100         im_debug.show(im_c, "first hough x lines")
101
102     collapse(im_c)
103     if show_all:
104         im_debug.show(im_c, "optimalised hough")
105
106     lines = hough1.all_lines(im_c)
107     draw = ImageDraw.Draw(image)
108     for line in lines:
109         draw.line(line_from_angl_dist(line, image.size), fill=(120, 255, 120))
110
111     im_debug.show(image, "the grid")
112
113     return 0
114
115 def collapse(image):
116     #HACK
117     im_l = image.load()
118     last = False
119     for y in xrange(image.size[1]):
120         for x in xrange(image.size[0]):
121             if im_l[x, y] and last:
122                 im_l[x, y] = 0
123                 last = False
124             elif im_l[x, y]:
125                 last = True
126             elif last:
127                 last = False
128
129 def combine(image1, image2):
130     im_l1 = image1.load()
131     im_l2 = image2.load()
132
133     im_n = Image.new('L', image1.size)
134     im_nl = im_n.load()
135
136     for x in xrange(image1.size[0]):
137         for y in xrange(image1.size[1]):
138             if im_l1[x, y] and im_l2[x, y]:
139                 im_nl[x, y] = 255
140     return im_n
141
142 def line_from_angl_dist((angle, distance), size):
143     x1 = - size[0] / 2
144     y1 = int(round((x1 * math.sin(angle) - distance)/math.cos(angle))) + size[1] / 2
145     x2 = size[0] / 2 
146     y2 = int(round((x2 * math.sin(angle) - distance)/math.cos(angle))) + size[1] / 2
147     return [(0, y1), (size[0] - 1, y2)]
148
149 if __name__ == '__main__':
150     sys.exit(main())