Commit 2393aae2 authored by Taddeüs Kroes's avatar Taddeüs Kroes

ImProc ass2: Implemented affine transformation.

parent d082e2e6
from interpolation import pv from interpolation import pv
from numpy import array, zeros from pylab import array, matrix, zeros, show
from numpy.linalg import lstsq, inv from numpy.linalg import lstsq, inv
# url: http://www.leptonica.com/affine.html # url: http://www.leptonica.com/affine.html
...@@ -19,43 +19,26 @@ def affine_transform(image, p1, p2, p3, width, height): ...@@ -19,43 +19,26 @@ def affine_transform(image, p1, p2, p3, width, height):
[x3, y3, 1, 0, 0, 0], [x3, y3, 1, 0, 0, 0],
[0, 0, 0, x3, y3, 1]]) [0, 0, 0, x3, y3, 1]])
q = array([[x1], q = array([[0],
[y1], [0],
[x2], [width],
[y2], [0],
[x3], [width],
[y3]]) [height]])
# Calculate transform matrix # Calculate transform matrix
p = lstsq(M, q)[0] a, b, c, d, e, f = lstsq(M, q)[0].T.tolist()[0]
T = p.reshape(2, 3).T A = matrix([[a, b, c],
T = inv(T) [d, e, f],
[0, 0, 1]]).I
# Construct the transformed image # Construct the transformed image
result = zeros((width, height)) result = zeros((width, height))
for y in xrange(height): for y in xrange(height):
for x in xrange(width): for x in xrange(width):
# TODO: multiplication using '*' or 'dot()' ? orig_pos = (A * array([[x, y, 1]]).T).T.tolist()[0]
# XXX: where is |0 0 1| in T, since p.reshape(2, 3) ? result[x][y] = pv(image, orig_pos[0], orig_pos[1], 'linear')
# |x'| |a b c| |x|
# |y'| = |d e f| |y|
# |1 | |0 0 1| |1|
orig_pos = array([x, y, 1]).reshape(3, 1) * T
#print x,y, tmp
print orig_pos, len(orig_pos)
# XXX Why is orig_pos in the format listed below?
#
# |g h|
# |i j|
# |k l|
#
result[y][x] = pv(image, orig_pos[0], orig_pos[1], 'linear')
return result return result
...@@ -70,7 +53,8 @@ if __name__ == '__main__': ...@@ -70,7 +53,8 @@ if __name__ == '__main__':
M, N = image.shape M, N = image.shape
# TODO: validate MxN -> width x height # TODO: validate MxN -> width x height
result = affine_transform(image, (0., 0.), (0., half_height), result = affine_transform(image, (0., half_height), (half_width, 0.),
(half_width, half_height), M, N) (image.shape[0], half_height), 128, 128)
imshow(result) imshow(result, cmap='gray')
show()
...@@ -6,22 +6,26 @@ def in_image(image, x, y): ...@@ -6,22 +6,26 @@ def in_image(image, x, y):
return x >= 0 and y >= 0 and x < image.shape[0] and y < image.shape[1] return x >= 0 and y >= 0 and x < image.shape[0] and y < image.shape[1]
def pv(image, x, y, method): def pv(image, x, y, method):
if not in_image(image, x, y):
return bgcolor
if method == 'nearest': if method == 'nearest':
return image[round(x)][round(y)] x, y = round(x), round(y)
return image[round(x)][round(y)] if in_image(image, x, y) else bgcolor
if method == 'linear': if method == 'linear':
x1 = floor(x) x1 = floor(x)
x2 = ceil(x) x2 = floor(x + 1)
y1 = floor(y) y1 = floor(y)
y2 = ceil(y) y2 = floor(y + 1)
if not in_image(image, x1, y1) or not in_image(image, x2, y2):
return bgcolor
diff = (x2 - x1) * (y2 - y1)
return image[x1][y1] * (x2 - x) * (y2 - y) \ return image[x1][y1] / diff * (x2 - x) * (y2 - y) \
+ image[x2][y1] * (x - x1) * (y2 - y) \ + image[x2][y1] / diff * (x - x1) * (y2 - y) \
+ image[x1][y2] * (x2 - x) * (y - y1) \ + image[x1][y2] / diff * (x2 - x) * (y - y1) \
+ image[x2][y2] * (x - x1) * (y - y1) + image[x2][y2] / diff * (x - x1) * (y - y1)
raise ValueError, 'Interpolation method "%s" is not supported' % method raise ValueError, 'Interpolation method "%s" is not supported' % method
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment