Skew Image without using OpenCV library
In this blog, you will find steps to skew an image without using OpenCV. Skewing is a geometrical transformation of an image where we can change the appearance of the image by using small matrix operations.
Effect of the transformation:
- squares become parallelograms
- y coordinates skew to the right
-
x coordinates stay the same
In python, the image axis is not as per the conventional X-Y axis. Below is the pictorial representation of rows and columns.
Let’s consider ROW as X-axis and COL as Y-axis. If we skew with respect to the ROW (X-axis), we will find a shape like shown in Image-2. Similarly, if we skew with respect to COL(Y-axis), we will find observations like shown in Image-3.
Effect of shearing along X-axis.
To shear an image, we have to multiply the below matrix to each point to skew the image.
import math
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
class ICV_shearImage:
def ICV_degreeToRadian(self, degree):
'''
Convert degree to radian
:param degree: degree
:return: radian
'''
return degree * np.pi / 180.0
def ICV_getImageMidPoints(self, image):
'''
This method returns image midpoints
:param image:
:return: x_mid, y_mid
'''
height, width, num_channels = image.shape
y_mid = width / 2
x_mid = height / 2
return x_mid, y_mid
def ICV_skew_XY(self, angle, x, y):
'''
This method implements the tangent rule to X and Y
:param angle:
:param x: X coordinate
:param y: Y coordinate
:return: new_x and new_y
'''
radian = self.ICV_degreeToRadian(angle)
tangent = 1 / math.tan(radian)
#new_x = round(x + (y * tangent))
#new_y = y
new_x = x
new_y = round(y + (x * tangent))
return new_x, new_y
def ICV_shear(self, image, angle, newimage):
'''
Shear the new image
:param image: Original Image matrix
:param angle: Degree
:param newimage: New image matrix
:return: New image
'''
x_mid, y_mid = self.ICV_getImageMidPoints(image)
newimage_x_mid, newimage_y_mid = self.ICV_getImageMidPoints(newimage)
for row in range(0,image.shape[0]):
for col in range(0,image.shape[1]):
y_prime = y_mid - col
x_prime = x_mid - row
x_new, y_new = self.ICV_skew_XY(angle, x_prime, y_prime)
xdist = int(newimage_x_mid - x_new)
ydist = int(newimage_y_mid - y_new)
if < newimage.shape[0] and ydist < newimage.shape[1]:
newimage[xdist, ydist, :] = image[row, col, :]
return newimage
def ICV_canvasSize(self, image, degree):
'''
Generate Canvas to hold skewed image
:param image: Image
:param degree: Degree
:return: Place holder to contain skewed image
'''
row, col, num_channels = image.shape
radian = self.ICV_degreeToRadian(degree)
new_y_value = round(row + (col * (1 / math.tan(radian))))
skewed_image_canvas = np.zeros((row, new_y_value, 3))
print("Skewed Image shape:", row, new_y_value)
return skewed_image_canvas
def ICV_plotImage(self, newImage, name):
'''
This method plots the new image
:param newImage:
:return: Null
'''
plt.gca().set_axis_off()
plt.margins(0, 0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
output_image = Image.fromarray(newImage.astype("uint8"))
plt.imshow(output_image)
plt.savefig("output_image_skewed"+name+".jpg",bbox_inches='tight', pad_inches=0)
plt.show()
def main():
shearimage = ICV_shearImage()
image = Image.open('name.jpg')
image = np.asarray(image)
row, col, num_channels = image.shape
print("Actual Image Shape:", row,col)
degree = 30
skewed_image_canvas = shearimage.ICV_canvasSize(image, degree)
newImage_30 = shearimage.ICV_shear(image, degree, skewed_image_canvas)
shearimage.ICV_plotImage(newImage_30, "30")
if __name__ == "__main__":
main()
Conclusion:
In this blog, you learned how to skew an image using python and skew an image without using OpenCV library. In the case of any queries please comment below.
#Skew Image without using OpenCV library