Inconsistencies between opencv WarpAffine and grid_sample

Hello, Im trying to reproduce an output from opencv WarpAffine on a reference image but get different results between opencv WarpAffine and Pytorch grid_sample function.

My transformation includes scaling, for some reason it does not seem to work using grid_sample function.
see the results below
On the right - the reference image size(64,64)
Middle - transformed image to 320,320 with a minor rotation
Left - grid_sample function output.
image

My code is attached here - reading an affine transform and apply using both methods.

import matplotlib.pyplot as plt


def _transform_matrix(Hs, w, h):
    _Hs = np.zeros(Hs.shape, dtype=np.float32)
    for i, H in enumerate(Hs):
        H0 = np.concatenate((H, np.array([[0, 0, 1]])), axis=0)
        A = np.array([[2.0 / w, 0, -1], [0, 2.0 / h, -1], [0, 0, 1]])
        A_inv = np.array([[w / 2.0, 0, w / 2.0], [0, h / 2.0, h / 2.0], [0, 0, 1]])
        H0 = A.dot(H0).dot(A_inv)
        H0 = np.linalg.inv(H0)
        _Hs[i] = H0[:-1]
    return _Hs

#get affine transform from an array
H_e2e = np.copy(self.TODOInversemaskAlignMatrixs[i][j])

#convert to theta
theta = _transform_matrix(H_e2e[np.newaxis, 0:2, :], 320,320)
theta = (torch.from_numpy(theta)).cuda()
grid = F.affine_grid(theta, (1, 1, 320, 320))

#predmap in an array of reference images. get one
img_ = F.grid_sample(torch.from_numpy(predmap[:, :, 0]).unsqueeze(0).unsqueeze(0).cuda().float(),
                     grid.float(), mode='bilinear')

fig = plt.figure()
ax1 = plt.subplot(1, 3, 1)
ax1.imshow(img_.squeeze().detach().cpu().numpy())

#do the same using opencv
pred_e2e = cv2.warpAffine(predmap[:, :, 0], H_e2e[0:2], (width, height))
ax2 = plt.subplot(1, 3, 2)
ax2.imshow(pred_e2e)

ax2 = plt.subplot(1, 3, 3)
ax2.imshow(predmap[:, :, 0])
1 Like