Shear an image without cropping

孤街浪徒 提交于 2019-12-11 06:05:44

问题


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 shear using affine transform and warp (skimage) the image appears "cropped" or "clipped" (some parts of the "sheared" image are lost) which has sense as far as shear transform moves pixels (involves a translation of pixels). I need that the "canvas" supporting the image scale so the "sheared" image fit in a new image but keeping all the information of the input image (image attached)


回答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



来源:https://stackoverflow.com/questions/44425701/shear-an-image-without-cropping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!