How to do it

You need to complete the following steps:

  1. Import the necessary modules, open an input image, and copy it:
import cv2
import numpy as np

img = cv2.imread('../data/circlesgrid.png', cv2.IMREAD_COLOR)
show_img = np.copy(img)
  1. Define two functions to implement the process of points selection :
selected_pts = []

def mouse_callback(event, x, y, flags, param):
global selected_pts, show_img

if event == cv2.EVENT_LBUTTONUP:
selected_pts.append([x, y])
cv2.circle(show_img, (x, y), 10, (0, 255, 0), 3)

def select_points(image, points_num):
global selected_pts
selected_pts = []

cv2.namedWindow('image')
cv2.setMouseCallback('image', mouse_callback)

while True:
cv2.imshow('image', image)

k = cv2.waitKey(1)

if k == 27 or len(selected_pts) == points_num:
break

cv2.destroyAllWindows()

return np.array(selected_pts, dtype=np.float32)
  1. Select three points in the image, compute the affine transformation with cv2.getAffineTransform, and apply it with cv2.warpAffine. Then, show the resulting images:
show_img = np.copy(img)
src_pts = select_points(show_img, 3)
dst_pts = np.array([[0, 240], [0, 0], [240, 0]], dtype=np.float32)

affine_m = cv2.getAffineTransform(src_pts, dst_pts)

unwarped_img = cv2.warpAffine(img, affine_m, (240, 240))

cv2.imshow('result', np.hstack((show_img, unwarped_img)))
k = cv2.waitKey()

cv2.destroyAllWindows()
  1. Find an inverse affine transformation, apply it, and display the results:
inv_affine = cv2.invertAffineTransform(affine_m)
warped_img = cv2.warpAffine(unwarped_img, inv_affine, (320, 240))

cv2.imshow('result', np.hstack((show_img, unwarped_img, warped_img)))
k = cv2.waitKey()

cv2.destroyAllWindows()
  1. Create a rotation-scale affine warp with cv2.getRotationMatrix2D and apply it to the image:
rotation_mat = cv2.getRotationMatrix2D(tuple(src_pts[0]), 6, 1)

rotated_img = cv2.warpAffine(img, rotation_mat, (240, 240))

cv2.imshow('result', np.hstack((show_img, rotated_img)))
k = cv2.waitKey()

cv2.destroyAllWindows()
  1. Select four points in the image, create a matrix for perspective warp with cv2.getPerspectiveTransform, and then apply it to the image and display the results:
show_img = np.copy(img)
src_pts = select_points(show_img, 4)
dst_pts = np.array([[0, 240], [0, 0], [240, 0], [240, 240]], dtype=np.float32)

perspective_m = cv2.getPerspectiveTransform(src_pts, dst_pts)

unwarped_img = cv2.warpPerspective(img, perspective_m, (240, 240))

cv2.imshow('result', np.hstack((show_img, unwarped_img)))
k = cv2.waitKey()

cv2.destroyAllWindows()