I'm encountering an issue with radial distortion in image processing. I'm trying to apply radial distortion to an image using distortion coefficients k_1 = 1 , k_2 = 0.4 and k_3 = 0.2 . According to the distortion model, I should be getting pincushion distortion as the output. However, when I tried two different methods, I got two different results.
Method 1: Bilinear Interpolation with Array Calculation
In this method, I used pure array calculation to apply radial distortion, the output is pincushion distortion. Here's the code I used:
def apply_distortion_jit(img,W,img_mat, k1, k2, k3):
    H = W
    dis_center_x = W/2
    dis_center_y = H/2
    for x in range(W-2):
        for y in range(H-2):
            x_norm = (x - dis_center_x)/ (W)
            y_norm = (y - dis_center_y)/ (H)
            r = x_norm * x_norm + y_norm * y_norm
            coeff = (k1 + k2 * r + k3 * (r ** 2))
            x_d = coeff * (x - W/2) + W/2
            y_d = coeff * (y - H/2) + H/2
            if x_d >= W-1 or y_d >= H-1 or x_d<0 or y_d <0:
                continue
            x_d_int = math.floor(x_d)
            y_d_int = math.floor(y_d)
            dx = x_d - x_d_int
            dy = y_d - y_d_int
            img_mat[y_d_int,x_d_int] = (1-dx)*(1-dy)*img[y,x] + dx*(1-dy)*img[y,x+1] + \
                               (1-dx)*dy*img[y+1,x] + dx*dy*img[y+1,x+1]
            img_mat[y_d_int,x_d_int+1] = (1-dx)*(1-dy)*img[y,x+1] + dx*(1-dy)*img[y,x+2] + \
                                    (1-dx)*dy*img[y+1,x+1] + dx*dy*img[y+1,x+2]
            img_mat[y_d_int+1,x_d_int] = (1-dx)*(1-dy)*img[y+1,x] + dx*(1-dy)*img[y+1,x+1] + \
                                    (1-dx)*dy*img[y+2,x] + dx*dy*img[y+2,x+1]
            img_mat[y_d_int+1,x_d_int+1] = (1-dx)*(1-dy)*img[y+1,x+1] + dx*(1-dy)*img[y+1,x+2] + \
                                    (1-dx)*dy*img[y+2,x+1] + dx*dy*img[y+2,x+2]
    return img_mat
Bilinear Interpolation output image
Method 2: Interpolation with scipy.ndimage.map_coordinates
In this method, I used scipy.ndimage.map_coordinates to apply radial distortion. I expected to get pincushion distortion, but the output showed barrel distortion. Here's the code :
def apply_distortion_scipy(img,W, k1, k2, k3):
    H = W
    x, y = np.meshgrid(np.float32(np.arange(W)), np.float32(np.arange(H)))  # meshgrid for interpolation mapping
    dis_center_x = W / 2
    dis_center_y = W / 2
    x_norm = (x - dis_center_x) / (W)
    y_norm = (y - dis_center_y) / (H)
    r = x_norm * x_norm + y_norm * y_norm
    coeff = (k1 + k2 * r + k3 * (r ** 2))
    x_d = coeff * (x - W / 2) + W / 2
    y_d = coeff * (y - H / 2) + H / 2
    # img = np.array(img)
    img_mat = scipy.ndimage.map_coordinates(img, [y_d.ravel(), x_d.ravel()])
    img_mat.resize(img.shape)
    return img_mat
scipy.ndimage.map_coordinates output image
I have looked through the API Reference of scipy.ndimage.map_coordinates, but there are no specific implementation codes. Can anyone tell me what could be wrong with my issue?
