annotate tools/image_transforms.py @ 2:7ac913487a09 default tip

README modified
author tomasz-bednarz
date Tue, 26 Nov 2013 13:41:11 +1100
parents 64374d852e36
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
1 """Transformations on images"""
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
2 from numpy import random
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
3 from numpy import array
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
4 from PIL import Image
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
5 from PIL import ImageDraw
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
6 from PIL import ImageOps
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
7
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
8 def tileify(image_data, num_blocks, max_shift):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
9 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
10 Breaks image up into rectangles and shifts them a random distance
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
11 Areas not covered by the moved rectangles are the negative of
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
12 the original image
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
13 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
14 width = image_data.size[0]
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
15 height = image_data.size[1]
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
16 row_block_size = round(height / num_blocks)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
17 col_block_size = round(width / num_blocks)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
18 negative_image = ImageOps.invert(image_data)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
19 pixels = array(image_data)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
20 for row in xrange(num_blocks):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
21 inner_row_val = int(row_block_size * row)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
22 outer_row_val = int(row_block_size * row + row_block_size)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
23 for col in xrange(num_blocks):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
24 inner_col_val = int(col_block_size * col)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
25 outer_col_val = int(col_block_size * col + col_block_size)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
26 block = pixels[
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
27 inner_row_val:outer_row_val,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
28 inner_col_val:outer_col_val
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
29 ]
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
30 location = calculate_random_location(
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
31 inner_row_val,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
32 inner_col_val,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
33 max_shift
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
34 )
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
35 negative_image.paste(Image.fromarray(block), location)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
36 return negative_image
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
37
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
38 def calculate_random_location(x, y, max_shift):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
39 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
40 Calculates random location near some starting point
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
41 Inputs
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
42 x - coordinate point where 0,0 is upper left corner
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
43 y - coordinate point where 0,0 is upper left corner
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
44 max_shift - the furthest distance from the point to shift
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
45 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
46 x_offset = random.random_integers(-max_shift, max_shift)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
47 y_offset = random.random_integers(-max_shift, max_shift)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
48 location = (
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
49 y + y_offset,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
50 x + x_offset
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
51 )
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
52 return location
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
53
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
54 def filmify_image(image_data):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
55 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
56 Makes the image look like 35mm film
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
57 Inputs:
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
58 PIL Image
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
59 Returns:
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
60 Modified image data
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
61 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
62 # print 'Filming'
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
63 # Size of photo in side the film
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
64 film_size = (400, 300)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
65 border_size = 30
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
66 film_hole_size = (8, 10)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
67
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
68 filmed_image = modify_photo(image_data, film_size)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
69 filmed_image = add_film_border(filmed_image, film_size, border_size)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
70
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
71 # Center strip in the border space
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
72 strip_upper_offset = int(round((border_size - film_hole_size[1])/2))
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
73 strip_lower_offset = film_size[1] + border_size + strip_upper_offset
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
74 # Bring strip in towards the photo
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
75 offset = int(round(film_hole_size[1]/2))
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
76 strip_upper_offset = strip_upper_offset + offset
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
77 strip_lower_offset = strip_lower_offset - offset
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
78
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
79 place_film_strip(
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
80 filmed_image,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
81 strip_upper_offset,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
82 strip_lower_offset,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
83 film_hole_size
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
84 )
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
85
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
86 return filmed_image
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
87
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
88 def add_film_border(image_data, film_size, border_size):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
89 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
90 Creates a black border around the image
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
91 Inputs
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
92 image_data - image to be manipulated
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
93 film_size - size of the internal picture
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
94 border_size - how wide you want the border on the top and bottom to be
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
95 Output
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
96 image with border
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
97 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
98 image_data = ImageOps.expand(
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
99 image_data,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
100 border=border_size,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
101 fill='black'
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
102 )
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
103 # Crop to cut half of border from right and left of image
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
104 crop_box = (
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
105 int(round(border_size/2)),
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
106 0,
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
107 film_size[0] + int(round(border_size * 1.5)),
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
108 film_size[1] + border_size * 2
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
109 )
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
110 image_data = image_data.crop(crop_box)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
111 return image_data
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
112
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
113 def place_film_strip(image_data, y_offset_upper, y_offset_lower, film_hole_size):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
114 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
115 Create strip of film_holes at y_offset
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
116 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
117 hole_distance = 15
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
118 left_film_buffer = 2
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
119 for x_offset in range(left_film_buffer, image_data.size[0], hole_distance):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
120 place_film_hole(image_data, (x_offset, y_offset_upper), film_hole_size)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
121 place_film_hole(image_data, (x_offset, y_offset_lower), film_hole_size)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
122
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
123 def place_film_hole(image_data, offset, film_hole_size):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
124 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
125 Puts film hole at offset into the image provided
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
126 Inputs:
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
127 image_data - image file to have film hole pasted
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
128 offset - 2 tuple with x and y of the top left corner of film hole
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
129 film_hole_size - size of the rectangle to be made
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
130 Outputs
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
131 Original image with rectangle in location based on the offset
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
132 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
133 corner_radius = 2
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
134 film_hole_color = 'white'
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
135 film_hole = round_rectangle(film_hole_size, corner_radius, film_hole_color)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
136 image_data.paste(film_hole, offset)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
137
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
138 def round_corner(radius, fill):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
139 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
140 Draw a round corner
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
141 This code came from http://nadiana.com/pil-tutorial-basic-advanced-drawing
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
142 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
143 corner = Image.new('RGBA', (radius, radius), (0, 0, 0, 0))
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
144 draw = ImageDraw.Draw(corner)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
145 draw.pieslice((0, 0, radius * 2, radius * 2), 180, 270, fill=fill)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
146 return corner
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
147
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
148 def round_rectangle(size, radius, fill):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
149 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
150 Draw a rounded rectangle
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
151 This code came from http://nadiana.com/pil-tutorial-basic-advanced-drawing
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
152 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
153 width, height = size
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
154 rectangle = Image.new('RGBA', size, fill)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
155 corner = round_corner(radius, fill)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
156 rectangle.paste(corner, (0, 0))
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
157 # Rotate the corner and paste it
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
158 rectangle.paste(corner.rotate(90), (0, height - radius))
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
159 rectangle.paste(corner.rotate(180), (width - radius, height - radius))
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
160 rectangle.paste(corner.rotate(270), (width - radius, 0))
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
161 return rectangle
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
162
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
163 def modify_photo(image_data, film_size):
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
164 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
165 Make the image grayscale and invert the colors
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
166 All manipulations for the original photo go here
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
167 """
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
168 modified_image = ImageOps.grayscale(image_data)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
169 # Image.ANTIALIAS is best for down sizing
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
170 modified_image = modified_image.resize(film_size, Image.ANTIALIAS)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
171 modified_image = ImageOps.invert(modified_image)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
172 modified_image = ImageOps.flip(modified_image)
64374d852e36 Uploaded
tomasz-bednarz
parents:
diff changeset
173 return modified_image