Affine Transformations In Depth

Rohit Krishna
Geek Culture
Published in
3 min readApr 6, 2023
Photo by Sebastian Svenson on Unsplash

Affine Transformations are Certain Matrix/Image Transformations. What is unique about Affine Transformations is that these are very basic and widely used.

Some of the Common Affine Transformations are,

  1. Translation
  2. Change of Scale (Expand/Shrink)
  3. Rotation
  4. Skewing
  5. Panoramic Distortion
  6. etc…

How do we perform these transformations?

We can perform the transformation to any image by doing dot product with certain matrices. Below you can see some of the transformation and matrices used.

Below is the function for warping affine transformation using a matrix to an image.

Ok that works out to be great, but how can we perform transformation if we don’t know what matrix to use?

If you can convey your transformation, by giving three (x, y) points like src and dst then we can do that transformation as a piece of cake.

If your inputs are like follows,

the equation you want to solve would be like follows,

Image by Author

Since SRC is a square matrix, we can calculate matrix M by matrix multiplying inv(SRC) with DST.

below is the python function for that.

result of the above code

Ok, now we know how to transform, but how do we reverse the transformation?

we can perform the warpAffine to the image using the inverse of the affine matrix, remember that we can only reverse the image to exact original form, only if the transformed image has all the data from the original form.

below is the code block for invertAffineTransform,

result of the above code

Conclusion

I hope you now have a clear understanding of Affine Transformations and the math behind them.

When you work on real-world projects you don’t have to do all this struggle, you can use libraries such as OpenCV for your needs. In Python using OpenCV, you can perform the explained algorithms as shown below,

img = cv2.imread('<path-to-img>')

th = np.radians(20)
M = np.float32([[np.cos(th), np.sin(th), 100], [-np.sin(th), np.cos(th), 250]])
shape = (img.shape[0] + 400, img.shape[1] + 400)
rows, cols, _ = img.shape

def r():
return (random.random() - 0.5) * .3 * cols


res = cv2.warpAffine(img, M, shape)


_from = np.float32([[0, 0], [cols, rows], [0, rows]])
_to = np.float32([[r(), r()], [cols + r(), rows + r()], [r(), rows + r()]])

M = cv2.getAffineTransform(_from, _to)
dst = cv2.warpAffine(img, M, shape)

M_inv = cv2.invertAffineTransform(M)
res_inv = cv2.warpAffine(res, M_inv, (img.shape[0], img.shape[1]))

References

  1. https://github.com/OlehOnyshchak/ImageTransformations/blob/master/AffineTransformation.ipynb
  2. https://numpy.org/doc/stable/reference/generated/numpy.linalg.solve.html
  3. https://youtu.be/E3Phj6J287o?si=yqEos9ASACwI7WHQ

--

--