The atXY()
call is to check that the points used to make the bicubic interpolation are inside the frame limits.
The function as Carlton said and I confirmed, it is a bicubic interpolation to extract the value of a subpixel in any location inside the image.
I was trying to translate the code to python, and I finally perform the following code that gives the same result of CImg.h function.
*Take into account that I implement directly the atXY()
function with logical operators and that the indexes (x,y) are changed to (y,x) because python uses (idRow,idCol) for the matrix index
def bicubic(fx, fy, img):
img = img.astype(float)
h,w = np.shape(img)
if(fx < 0 or fx > w-1 or fy < 0 or fy > h-1):
val = 0
return val
x = int(fx)
y = int(fy)
dx = fx - x
dy = fy - y
px = 0 if x-1<0 else x-1
py = 0 if y-1<0 else y-1
nx = x+1 if dx>0 else x
ny = y+1 if dy>0 else y
ax = w-1 if x+2>=w else x+2
ay = h-1 if y+2>=h else y+2
Ipp = img[py,px]; Icp = img[py,x]; Inp = img[py,nx]; Iap = img[py,ax];
Ip = Icp + 0.5*(dx*(-Ipp+Inp) + dx*dx*(2*Ipp-5*Icp+4*Inp-Iap) + dx*dx*dx*(-Ipp+3*Icp-3*Inp+Iap))
Ipc = img[y,px]; Icc = img[y,x]; Inc = img[y,nx]; Iac = img[y,ax];
Ic = Icc + 0.5*(dx*(-Ipc+Inc) + dx*dx*(2*Ipc-5*Icc+4*Inc-Iac) + dx*dx*dx*(-Ipc+3*Icc-3*Inc+Iac))
Ipn = img[ny,px]; Icn = img[ny,x]; Inn = img[ny,nx]; Ian = img[ny,ax];
In = Icn + 0.5*(dx*(-Ipn+Inn) + dx*dx*(2*Ipn-5*Icn+4*Inn-Ian) + dx*dx*dx*(-Ipn+3*Icn-3*Inn+Ian))
Ipa = img[ay,px]; Ica = img[ay,x]; Ina = img[ay,nx]; Iaa = img[ay,ax];
Ia = Ica + 0.5*(dx*(-Ipa+Ina) + dx*dx*(2*Ipa-5*Ica+4*Ina-Iaa) + dx*dx*dx*(-Ipa+3*Ica-3*Ina+Iaa))
val = Ic + 0.5*(dy*(-Ip+In) + dy*dy*(2*Ip-5*Ic+4*In-Ia) + dy*dy*dy*(-Ip+3*Ic-3*In+Ia))
return val