I want to shift an image by x
pixels while maintaining the original shape. I tried the following:
import cv2
img = cv2.imread("roi.jpg")
shift = img[:,x:size[1]]
But the problem with the above approach is that, the original shape of the image is lost. How could I preserve the original shape while shifting an image by x
pixels to the left.
In image processing, this thing is referred to as Translation of image.
The original image:
import cv2
import numpy as np
# Read image
img = cv2.imread("roi.jpg")
# The number of pixels
num_rows, num_cols = img.shape[:2]
# Creating a translation matrix
translation_matrix = np.float32([ [1,0,70], [0,1,110] ])
# Image translation
img_translation = cv2.warpAffine(img, translation_matrix, (num_cols,num_rows))
#cv2.namedWindow('Translation', cv2.WINDOW_NORMAL)
cv2.imshow('Translation', img_translation)
cv2.waitKey(0)
cv2.destroyAllWindows()
This will give you:
But we want something like this:
Translation basically means that we are shifting the image by adding/subtracting the X and Y coordinates. In order to do this, we need to create a transformation matrix, as shown as follows:
Here, the tx and ty values are the X and Y translation values, that is, the image will be moved by X units towards the right, and by Y units downwards.
So once we create a matrix like this, we can use the function, warpAffine, to apply to our image.
The third argument in warpAffine refers to the number of rows and columns in the resulting image. Since the number of rows and columns is the same as the original image, the resultant image is going to get cropped. The reason for this is because we didn't have enough space in the output when we applied the translation matrix. To avoid cropping, we can do something like this:
img_translation = cv2.warpAffine(img, translation_matrix, (num_cols + 70, num_rows + 110))
cv2.namedWindow('Translation', cv2.WINDOW_NORMAL)
cv2.imshow('Translation', img_translation)
cv2.waitKey(0)
cv2.destroyAllWindows()
And this will result in:
Remember this image is resized while being uploaded here, don't worry, this is your desired result.
Moreover, if we want to move the image in the middle of a bigger image frame; we can do something like this by carrying out the following:
num_rows, num_cols = img.shape[:2]
translation_matrix = np.float32([ [1,0,70], [0,1,110] ])
img_translation = cv2.warpAffine(img, translation_matrix, (num_cols + 70, num_rows + 110))
translation_matrix = np.float32([ [1,0,-30], [0,1,-50] ])
img_translation = cv2.warpAffine(img_translation, translation_matrix, (num_cols + 70 + 30, num_rows + 110 + 50))
cv2.namedWindow('Translation', cv2.WINDOW_NORMAL)
cv2.imshow('Translation', img_translation)
cv2.waitKey(0)
cv2.destroyAllWindows()
Which gives you the output as:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With