0

I am trying to understand what a code is doing that uses CImg.h file of C++ Image Processing Toolkit for extract a value from an image.

The function uses the following statement:

float dx(float x, float y, CImg<float> &i) {
    float val = i.cubic_atXY(x + 0.5, y);
    return val;
}

I think that it is trying to find the cubic interpolated subpixel on coordinate (x+0.5,y). I found that this functions are defined near line 12450 on the CImg.h file, but I really do not not how to translate it to other code such as python.

Someone that uses this kind of libraries is able to understand it?

iblasi
  • 1,269
  • 9
  • 21

2 Answers2

0

cubic_atXY is some tedious-looking code, but it is basically all simple arithmetic operations that should have similar syntax in other programming languages. The only lines that are not generic are like this, for example:

const Tfloat Ipp = (Tfloat)atXY(px,py,z,c,out_value)

which is a C-style cast. It casts the result of the call to atXY() to a Tfloat. This looks like bicubic interpolation by the way.

Carlton
  • 4,217
  • 2
  • 24
  • 40
  • It is a bicubic interpolation as you can see in this other [code](http://sourceforge.net/mirror/photivo/code/ci/583ec9ba1f528c40c002f9f6206dba7c90461e18/tree/Sources/ptImage_Lensfun.cpp#l100). It makes a bicubic interpolation to see the value in that exact point. Python has not got functions to determine this point value from a grid as I can see. – iblasi May 12 '15 at 17:19
  • Check out [SciPy's Interpolation Functions](http://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html), it might have what you need. – Carlton May 12 '15 at 19:12
0

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
iblasi
  • 1,269
  • 9
  • 21