Reputation: 942
I have problems with the im.transform method in PIL python library. I thought I figured out the logic of parameters, A to F, however, the resulting image gets rotated in the wrong direction and cut off although all four corners calculated by the bellow function have correct positive values.
Could anybody give me formulas to calculate affine parameters (A to F) from three identical points in both coordinate systems?
def tran (x_pic, y_pic, A, B, C, D, E, F):
X = A * x_pic + B * y_pic + C
Y = D * x_pic + E * y_pic + F
return X, Y
Upvotes: 6
Views: 13379
Reputation: 955
I think my version of is much more explicit and easy to understand.
def scale_rotate_translate(image, angle, sr_center=None, displacement=None, scale=None):
if sr_center is None:
sr_center = 0, 0
if displacement is None:
displacement = 0, 0
if scale is None:
scale = 1, 1
angle = -angle / 180.0 * np.pi
C = np.array([[1, 0, -sr_center[0]],
[0, 1, -sr_center[1]],
[0, 0, 1]])
C_1 = np.linalg.inv(C)
S = np.array([[scale[0], 0, 0],
[0, scale[1], 0],
[0, 0, 1]])
R = np.array([[np.cos(angle), np.sin(angle), 0],
[-np.sin(angle), np.cos(angle), 0],
[0, 0, 1]])
D = np.array([[1, 0, displacement[0]],
[0, 1, displacement[1]],
[0, 0, 1]])
Mt = np.dot(D, np.dot(C_1, np.dot(R, np.dot(S, C))))
a, b, c = Mt[0]
d, e, f = Mt[1]
return image.transform(image.size, Image.AFFINE, (a, b, c, d, e, f), resample=Image.BICUBIC)
Upvotes: 1
Reputation: 3797
transform works fine for me. As an example we'll rotate an image around a center different from (0,0) with optional scaling and translation to a new center. Here is how to do it with transform:
def ScaleRotateTranslate(image, angle, center = None, new_center = None, scale = None,expand=False):
if center is None:
return image.rotate(angle)
angle = -angle/180.0*math.pi
nx,ny = x,y = center
sx=sy=1.0
if new_center:
(nx,ny) = new_center
if scale:
(sx,sy) = scale
cosine = math.cos(angle)
sine = math.sin(angle)
a = cosine/sx
b = sine/sx
c = x-nx*a-ny*b
d = -sine/sy
e = cosine/sy
f = y-nx*d-ny*e
return image.transform(image.size, Image.AFFINE, (a,b,c,d,e,f), resample=Image.BICUBIC)
Upvotes: 15