Yeah. Below is a Python script. I used OpenCV to transform image by coordinates.
import numpy as np
import cv2 as cv2
def toHomo(mx, my, width, height, focal, ppU, ppV):
scale = max(width, height)
px = ((mx - width / 2) / scale - ppU) * 35.0 / focal
py = ((my - height / 2) / scale - ppV) * 35.0 / focal
return px, py
def fromHomo(px, py, width, height, focal, ppU, ppV):
scale = max(width, height)
mx = (px * focal / 35 + ppU) * scale + width / 2
my = (py * focal / 35 + ppV) * scale + height / 2
return mx, my
def brownDistortion(x0, y0, k1, k2, k3, p1, p2):
x2 = x0 * x0
y2 = y0 * y0
xy = x0 * y0
r2 = x2 + y2
k = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2
tx = p1 * (r2 + x2) + 2 * p2 * xy
ty = p2 * (r2 + y2) + 2 * p1 * xy
return x0 * k + tx, y0 * k + ty
original = cv2.imread(“image.jpg”)
#data from .XMP
height = len(original)
width = len(original[0])
focal = 60
scale = max(width, height)
#order k1 k2 p2 p1 k3
distKoeff = np.array([0.1, 0.5, 0, 0, 1])
pp = [0.001, 0.002]
mapX = np.zeros((height, width), np.float32)
mapY = np.zeros((height, width), np.float32)
for row in range(0, height):
for col in range(0, width):
mx, my = toHomo(col + 0.5, row + 0.5, width, height,focal, pp[0], pp[1])
mx, my = brownDistortion(mx,my,distKoeff[0], distKoeff[1],distKoeff[4],distKoeff[2], distKoeff[3])
px, py = fromHomo(mx, my,width, height, focal,pp[0],pp[1])
mapX[row][col] = px - 0.5
mapY[row][col] = py - 0.5
result = cv2.remap(original,mapX,mapY, cv2.INTER_CUBIC)
cv2.imwrite(“result.jpg”,result)