Skip to content Skip to sidebar Skip to footer

Shear An Image Without Cropping

I am trying to do a shear transformation on images using python. I am using skimage (scikit-image), opencv or similar can also do the job i think. The problem is whenever I try to

Solution 1:

I got the same trouble and I finally manage to found a solution that work well with the images I tested. I was using the fact that I want to apply shear, rotation and translation transformation on the image.

  1. First, we calculate the necessary space for the rotation (don't need to calculate if not used).
  2. Second, we calculate the necessary space for the last pixel of the image that will have the maximal translation in the image by the shear.
  3. Third, we need to calculate the translation necessary to compensate the fact that the shear will move the center of the image.

If you want all your images to be the same size, then use an angle of 45 degrees because it's the angle that need the more space.

import numpy as np
import cv2

#Parameters of the affine transform:
angle = 45; #Angle in degrees.
shear = 1;
translation = 5;

type_border = cv2.BORDER_CONSTANT;
color_border = (255,255,255);

original_image = cv2.imread(name_image_file);
rows,cols,ch = original_image.shape;

#First: Necessary space for the rotation
M = cv2.getRotationMatrix2D((cols/2,rows/2), angle, 1);
cos_part = np.abs(M[0, 0]); sin_part = np.abs(M[0, 1]);
new_cols = int((rows * sin_part) + (cols * cos_part)); 
new_rows = int((rows * cos_part) + (cols * sin_part));

#Second: Necessary space for the shear
new_cols += (shear*new_cols);
new_rows += (shear*new_rows);

#Calculate the space to add with border
up_down = int((new_rows-rows)/2); left_right = int((new_cols-cols)/2);

final_image = cv2.copyMakeBorder(original_image, up_down, up_down,left_right,left_right,type_border, value = color_border);
rows,cols,ch = final_image.shape;

#Application of the affine transform.
M_rot = cv2.getRotationMatrix2D((cols/2,rows/2),angle,1);
translat_center_x = -(shear*cols)/2;
translat_center_y = -(shear*rows)/2;

M = M_rot + np.float64([[0,shear,translation + translat_center_x], [shear,0,translation + translat_center_y]]);
final_image  = cv2.warpAffine(final_image , M, (cols,rows),borderMode = type_border, borderValue = color_border);

Example (where I put the border of "cv2.copyMakeBorder" and "cv2.getRotationMatrix2D" to white): Angle = -45 degrees. Shear = -0.5

Original image

Shear = -0.5, rotation of -45 degrees

Post a Comment for "Shear An Image Without Cropping"