# How to use torchvision transform shearing for x and y direction?

In TensorFlow, one can define shearing in x and y direction independently, such as:

``````image = tf.contrib.image.transform(image, [1., level, 0., 0., 1., 0., 0., 0.]) #x direction
image = tf.contrib.image.transform(image, [1., 0., 0., level, 1., 0., 0., 0.]) #y direction
``````

However, in Pytorch, there is only 1 option, such as:

``````import torchvision.transforms.functional as TF
image = TF.affine(image,degrees=0,translate=None,scale=None,shear=level)
``````

How to do it appropriately with Pytorch? Thank you

I think this functionality could be added in _get_inverse_affine_matrix by providing the `shear` argument as a `list` or `tuple`.
These would probably be the necessary changes:

``````def _get_inverse_affine_matrix(center, angle, translate, scale, shear):
# Helper method to compute inverse matrix for affine transformation

# As it is explained in PIL.Image.rotate
# We need compute INVERSE of affine transformation matrix: M = T * C * RSS * C^-1
# where T is translation matrix: [1, 0, tx | 0, 1, ty | 0, 0, 1]
#       C is translation matrix to keep center: [1, 0, cx | 0, 1, cy | 0, 0, 1]
#       RSS is rotation with scale and shear matrix
#       RSS(a, scale, shear) = [ cos(a)*scale    -sin(a + shear)*scale     0]
#                              [ sin(a)*scale    cos(a + shear)*scale     0]
#                              [     0                  0          1]
# Thus, the inverse is M^-1 = C * RSS^-1 * C^-1 * T^-1

if isinstance(shear, (tuple, list)) and len(shear) == 2:
else:
shear = [shear, shear]

scale = 1.0 / scale

# Inverted rotation matrix with scale and shear
d = math.cos(angle + shear) * math.cos(angle + shear) + math.sin(angle + shear) * math.sin(angle + shear)
matrix = [
math.cos(angle + shear), math.sin(angle + shear), 0,
-math.sin(angle + shear), math.cos(angle + shear), 0
]
matrix = [scale / d * m for m in matrix]

# Apply inverse of translation and of center translation: RSS^-1 * C^-1 * T^-1
matrix += matrix * (-center - translate) + matrix * (-center - translate)
matrix += matrix * (-center - translate) + matrix * (-center - translate)

# Apply center translation: C * RSS^-1 * C^-1 * T^-1
matrix += center
matrix += center
return matrix
``````

CC @fmassa
Let me know, if that looks good and I could create a PR for it.

This seems good to me at first, could you open a PR in torchvision and we can discuss further?

1 Like

@Chuong98 the PR is merged so you could build `torchvision` from master to enable shear parallel to the x- and y-axis.

2 Likes