parameters
[imago.git] / src / hough.py
1 """Hough transform module."""
2
3 from math import pi
4
5 from PIL import Image
6
7 import pcf
8
9 class Hough:
10     """Hough transform.
11
12     This class stores the parameters of the transformation.
13     """
14     def __init__(self, size, dt, init_angle):
15         self.size = size # this is a tuple (width, height)
16         self.dt = dt     # this is the angle step in hough transform
17         self.initial_angle = init_angle
18
19     @classmethod
20     def default(cls, image):
21         """Default parameters for Hough transform of the *image*."""
22         size = image.size
23         dt = pi / size[1]
24         initial_angle = (pi / 4) + (dt / 2)
25         return cls(size, dt, initial_angle)
26
27     def transform(self, image):
28         image_s = pcf.hough(self.size, image.tostring(), self.initial_angle,
29                             self.dt)
30         image_t = Image.fromstring('L', self.size, image_s)
31         return image_t
32
33     def apply_filter(self, filter_f):
34         return Hough(self.size, self.dt, self.initial_angle,
35                      filter_f(self.image))
36
37     def lines_from_list(self, p_list):
38         """Take a list of transformed points and return a list of corresponding
39         lines as (angle, distance) tuples."""
40         # TODO! why is distance allways integer?
41         lines = []
42         for p in p_list:
43             lines.append(self.angle_distance(p))
44         return lines
45
46     def all_lines_h(self, image):
47         # TODO what is this?
48         im_l = image.load()
49         lines1 = []
50         for x in xrange(self.size[0] / 2):
51             for y in xrange(self.size[1]):
52                 if im_l[x, y]:
53                     lines1.append(self.angle_distance((x, y)))
54         lines2 = []
55         for x in xrange(self.size[0] / 2, self.size[0]):
56             for y in xrange(self.size[1]):
57                 if im_l[x, y]:
58                     lines2.append(self.angle_distance((x, y)))
59         return [lines1, lines2]
60
61     def all_lines(self):
62         # TODO what is this? how does it differ from the upper one?
63         im_l = self.image.load()
64         lines = []
65         for x in xrange(self.size[0]):
66             for y in xrange(self.size[1]):
67                 if im_l[x, y]:
68                     lines.append(self.angle_distance((x, y)))
69         return lines
70     
71     def angle_distance(self, point):
72         """Take a point from the transformed image and return the corresponding
73         line in the original as (angle, distance) tuple."""
74         return (self.dt * point[1] + self.initial_angle,
75                 point[0] - self.size[0] / 2)
76