Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shifting an image by x pixels to left while maintaining the original shape

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.

like image 300
Suhail Gupta Avatar asked Jan 02 '23 09:01

Suhail Gupta


1 Answers

In image processing, this thing is referred to as Translation of image.

The original image:

enter image description here

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:

enter image description here

But we want something like this:

enter image description here

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:

enter image description here

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:

enter image description here

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:

enter image description here

like image 153
Amit Amola Avatar answered Jan 28 '23 22:01

Amit Amola