Inverse Bilinear Interpolation?

后端 未结 8 1489
礼貌的吻别
礼貌的吻别 2020-12-12 14:14

I have four 2d points, p0 = (x0,y0), p1 = (x1,y1), etc. that form a quadrilateral. In my case, the quad is not rectangular, but it should at least be convex.



        
8条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-12 14:28

    this is my implementation ... I guess it is faster than of tfiniga

    void invbilerp( float x, float y, float x00, float x01, float x10, float x11,  float y00, float y01, float y10, float y11, float [] uv ){
    
    // substition 1 ( see. derivation )
    float dx0 = x01 - x00;
    float dx1 = x11 - x10;
    float dy0 = y01 - y00;
    float dy1 = y11 - y10;
    
    // substitution 2 ( see. derivation )
    float x00x = x00 - x;
    float xd   = x10 - x00;
    float dxd  = dx1 - dx0; 
    float y00y = y00 - y;
    float yd   = y10 - y00;
    float dyd  = dy1 - dy0;
    
    // solution of quadratic equations
    float c =   x00x*yd - y00y*xd;
    float b =   dx0*yd  + dyd*x00x - dy0*xd - dxd*y00y;
    float a =   dx0*dyd - dy0*dxd;
    float D2 = b*b - 4*a*c;
    float D  = sqrt( D2 );
    float u = (-b - D)/(2*a);
    
    // backsubstitution of "u" to obtain "v"
    float v;
    float denom_x = xd + u*dxd;
    float denom_y = yd + u*dyd;
    if( abs(denom_x)>abs(denom_y) ){  v = -( x00x + u*dx0 )/denom_x;  }else{  v = -( y00y + u*dy0 )/denom_y;  }
    uv[0]=u;
    uv[1]=v;
    
    /* 
    // do you really need second solution ? 
    u = (-b + D)/(2*a);
    denom_x = xd + u*dxd;
    denom_y = yd + u*dyd;
    if( abs(denom_x)>abs(denom_y) ){  v = -( x00x + u*dx0 )/denom_x;  }else{  v2 = -( y00y + u*dy0 )/denom_y;  }
    uv[2]=u;
    uv[3]=v;
    */ 
    }
    

    and derivation

    // starting from bilinear interpolation
    (1-v)*(  (1-u)*x00 + u*x01 ) + v*( (1-u)*x10 + u*x11 )     - x
    (1-v)*(  (1-u)*y00 + u*y01 ) + v*( (1-u)*y10 + u*y11 )     - y
    
    substition 1:
    dx0 = x01 - x00
    dx1 = x11 - x10
    dy0 = y01 - y00
    dy1 = y11 - y10
    
    we get:
    (1-v) * ( x00 + u*dx0 )  + v * (  x10 + u*dx1  )  - x   = 0
    (1-v) * ( y00 + u*dy0 )  + v * (  y10 + u*dy1  )  - y   = 0
    
    we are trying to extract "v" out
    x00 + u*dx0   + v*(  x10 - x00 + u*( dx1 - dx0 ) )  - x = 0
    y00 + u*dy0   + v*(  y10 - y00 + u*( dy1 - dy0 ) )  - y = 0
    
    substition 2:
    x00x = x00 - x
    xd   = x10 - x00
    dxd  = dx1 - dx0 
    y00y = y00 - y
    yd   = y10 - y00
    dyd  = dy1 - dy0 
    
    // much nicer
    x00x + u*dx0   + v*(  xd + u*dxd )  = 0
    y00x + u*dy0   + v*(  yd + u*dyd )  = 0
    
    // this equations for "v" are used for back substition
    v = -( x00x + u*dx0 ) / (  xd + u*dxd  )
    v = -( y00x + u*dy0 ) / (  yd + u*dyd  )
    
    // but for now, we eliminate "v" to get one eqution for "u"  
    ( x00x + u*dx0 ) / (  xd + u*dxd )  =  ( y00y + u*dy0 ) / (  yd + u*dyd  )
    
    put denominators to other side
    
    ( x00x + u*dx0 ) * (  yd + u*dyd )  =  ( y00y + u*dy0 ) * (  xd + u*dxd  )
    
    x00x*yd + u*( dx0*yd + dyd*x00x ) + u^2* dx0*dyd = y00y*xd + u*( dy0*xd + dxd*y00y ) + u^2* dy0*dxd  
    
    // which is quadratic equation with these coefficients 
    c =   x00x*yd - y00y*xd
    b =   dx0*yd  + dyd*x00x - dy0*xd - dxd*y00y
    a =   dx0*dyd - dy0*dxd
    

提交回复
热议问题