Different behavior between opencv and pytorch image transforms

Some sample code from my notebook to start this off:

from skimage import io
import cv2
import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt
import numpy as np

test_image = io.imread(“https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_(test_image).png”)

Create transformation matrix

M1 = np.array([[1,0,0.5],[0,1,0],[0,0,1]]).astype(np.float32)

Apply transformation matrix using OpenCV

cv2im = cv2.warpAffine(test_image, M1[0:2], (test_image.shape[1], test_image.shape[0]))

Reshape image for PyTorch convention and apply same transformation matrix

temp_test_image = torch.tensor(np.moveaxis(test_image.astype(np.float32), -1, 0))
grid = F.affine_grid(torch.tensor(M1)[0:2].unsqueeze(0), temp_test_image.unsqueeze(0).shape)
pytorchim = F.grid_sample(temp_test_image.unsqueeze(0), grid).squeeze(0)

Display results from both

%matplotlib inline
plt.title(“With OpenCV”)
plt.imshow(np.transpose(pytorchim.numpy(), (1,2,0))/255)

The results look like this:

So if I understand correctly, in case of the opencv transfrom, it correctly moves it right by barely half a pixel (barely noticeable, I know, but you can change the value and notice it’s effect). Whereas in case of the torch transform it seems to move it towards the left (?!) and also the scale is entirely different, since we see quite some movement even with 0.5. I think this is probably due to how we use the grid generated from affine_grid (range in [-1,1])? But could someone tell me how I can apply transforms with the same effects as in OpenCV and vice versa? Also I noticed for rotations, PyTorch rotates images about the center of the image, whereas the convention in OpenCV is to do it about the origin (which is top left corner of the image).

Thanks for your help!

use kornia.warp_affine

1 Like

Thanks @edgarriba. I’ll try it out. Could you tell me how it’s different?