Perform the following steps to apply a projective transformation to an image using the transform module from scikit-image:
- First, read the source image and create a destination image with the np.zeros() function:
im_src = (imread('images/humming2.png'))
height, width, dim = im_src.shape
im_dst = np.zeros((height, width, dim))
- Create an instance of the ProjectiveTransform class:
pt = ProjectiveTransform()
- You just need to provide four pairs of matching points between the source and destination images to estimate the homography matrix, H, automatically for you. Here, the four corners of the destination image and the four corners of the input hummingbird are provided as matching points, as shown in the following code block:
src = np.array([[ 295., 174.],
[ 540., 146. ],
[ 400., 777.],
[ 60., 422.]])
dst = np.array([[ 0., 0.],
[height-1, 0.],
[height-1, width-1],
[ 0., width-1]])
- Obtain the source pixel index corresponding to each pixel index in the destination:
x, y = np.mgrid[:height, :width]
dst_indices = np.hstack((x.reshape(-1, 1), y.reshape(-1,1)))
src_indices = np.round(pt.inverse(dst_indices), 0).astype(int)
valid_idx = np.where((src_indices[:,0] < height) & (src_indices[:,1] < width) &
(src_indices[:,0] >= 0) & (src_indices[:,1] >= 0))
dst_indicies_valid = dst_indices[valid_idx]
src_indicies_valid = src_indices[valid_idx]
- Copy pixels from the source to the destination images:
im_dst[dst_indicies_valid[:,0],dst_indicies_valid[:,1]] =
im_src[src_indicies_valid[:,0],src_indicies_valid[:,1]]
If you run the preceding code snippets, you will get an output like the following screenshot:
The next screenshot shows the source image of an astronaut on the moon and the destination image of the canvas. Again, by providing four pairs of mapping points in between the source (corner points) and destination (corners of the canvas), the task is pretty straightforward:
The following screenshot shows the output image after the projective transform: