vl_imwbackwardmx.c
Go to the documentation of this file.
00001 /* file:        imwbackward.c
00002 ** author:      Andrea Vedaldi
00003 ** description: Backward projection of an image.
00004 **/
00005 
00006 /*
00007 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00008 All rights reserved.
00009 
00010 This file is part of the VLFeat library and is made available under
00011 the terms of the BSD license (see the COPYING file).
00012 */
00013 
00014 /* TODO.
00015  * - Make a faster version for the uniform grid case.
00016  * - Rename variables.
00017  */
00018 
00019 #include <mexutils.h>
00020 
00021 #include <vl/generic.h>
00022 
00023 #include <math.h>
00024 #include <stdlib.h>
00025 
00028 #define greater(a,b) (a) > (b)
00029 #define getM(arg) mxGetM(in[arg])
00030 #define getN(arg) mxGetN(in[arg])
00031 #define getPr(arg) mxGetPr(in[arg])
00032 
00033 VL_INLINE int
00034 findNeighbor(double x, const double* X, int K) {
00035   int i = 0 ;
00036   int j = K - 1 ;
00037   int pivot = 0 ;
00038   double y = 0 ;
00039   if(x <  X[i]) return i-1 ;
00040   if(x >= X[j]) return j ;
00041 
00042   while(i < j - 1) {
00043     pivot = (i+j) >> 1 ;
00044     y = X[pivot] ;
00045     /*mexPrintf("%d %d %d %f %f\n",i,j,pivot,x,y) ;*/
00046     if(x < y) {
00047       j = pivot ;
00048     } else {
00049       i = pivot ;
00050     }
00051   }
00052   return i ;
00053 }
00054 
00055 void
00056 mexFunction(int nout, mxArray *out[],
00057             int nin, const mxArray *in[])
00058 {
00059   enum { X=0,Y,I,iwXp,iwYp } ;
00060   enum { wI=0, wIx, wIy } ;
00061 
00062   int M, N, Mp, Np, ip, jp ;
00063   double
00064     *X_pt,
00065     *Y_pt,
00066     *I_pt,
00067     *iwXp_pt,
00068     *iwYp_pt,
00069     *wI_pt,
00070     *wIx_pt   = 0,
00071     *wIy_pt   = 0 ;
00072 
00073   double Xmin, Xmax, Ymin, Ymax ;
00074   const double NaN = mxGetNaN() ;
00075 
00076   /* -----------------------------------------------------------------
00077    *                                               Check the arguments
00078    * -------------------------------------------------------------- */
00079   if (nin < 5) {
00080     vlmxError (vlmxErrNotEnoughInputArguments, NULL) ;
00081   }
00082   if (nin > 5) {
00083     vlmxError (vlmxErrTooManyOutputArguments, NULL) ;
00084   }
00085   if (nout > 3) {
00086     vlmxError (vlmxErrTooManyOutputArguments, NULL) ;
00087   }
00088 
00089   if (! vlmxIsPlainMatrix(in[I], -1, -1)) {
00090     vlmxError (vlmxErrInvalidArgument, "I is not a plain matrix.") ;
00091   }
00092 
00093   if (! vlmxIsPlainMatrix(in[iwXp], -1, -1)) {
00094     vlmxError(vlmxErrInvalidArgument, "iwXp is not a plain matrix.") ;
00095   }
00096 
00097   M = getM(I) ;
00098   N = getN(I) ;
00099   Mp = getM(iwXp) ;
00100   Np = getN(iwXp) ;
00101 
00102   if(!vlmxIsPlainMatrix(in[iwYp], Mp, Np)) {
00103     vlmxError(vlmxErrInvalidArgument,
00104               "iwXp is not a plain matrix of the same idmension of iwYp.") ;
00105   }
00106 
00107   if(!vlmxIsPlainVector(in[X],N) || !vlmxIsPlainVector(in[Y],M)) {
00108     vlmxError(vlmxErrInvalidArgument,
00109               "X and Y are not plain vectors with a length equal to the"
00110               " number of columns and rows of I.") ;
00111   }
00112 
00113   X_pt = getPr(X);
00114   Y_pt = getPr(Y) ;
00115   I_pt = getPr(I) ;
00116   iwXp_pt = getPr(iwXp) ;
00117   iwYp_pt = getPr(iwYp) ;
00118 
00119   /* Allocate the result. */
00120   out[wI] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ;
00121   wI_pt = mxGetPr(out[wI]) ;
00122 
00123   if (nout > 1) {
00124     out[wIx] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ;
00125     out[wIy] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ;
00126     wIx_pt = mxGetPr (out[wIx]) ;
00127     wIy_pt = mxGetPr (out[wIy]) ;
00128   }
00129 
00130   /* -----------------------------------------------------------------
00131    *                                                        Do the job
00132    * -------------------------------------------------------------- */
00133   Xmin = X_pt [0] ;
00134   Xmax = X_pt [N - 1] ;
00135   Ymin = Y_pt [0] ;
00136   Ymax = Y_pt [M - 1] ;
00137 
00138   if (nout <= 1) {
00139 
00140     /* optimized for only image output */
00141     for(jp = 0 ; jp < Np ; ++jp) {
00142       for(ip = 0 ; ip < Mp ; ++ip) {
00143         /* Search for the four neighbors of the backprojected point. */
00144         double x = *iwXp_pt++ ;
00145         double y = *iwYp_pt++ ;
00146         double z = NaN ;
00147 
00148         /* This messy code allows the identity transformation
00149          * to be processed as expected. */
00150         if(x >= Xmin && x <= Xmax &&
00151            y >= Ymin && y <= Ymax) {
00152           int j = findNeighbor(x, X_pt, N) ;
00153           int i = findNeighbor(y, Y_pt, M) ;
00154           double* pt  = I_pt + j*M + i ;
00155 
00156           /* Weights. */
00157           double x0 = X_pt[j] ;
00158           double x1 = (j < N-1) ? X_pt[j+1] : x0 + 1;
00159           double y0 = Y_pt[i] ;
00160           double y1 = (i < M-1) ? Y_pt[i+1] : y0 + 1;
00161           double wx = (x-x0)/(x1-x0) ;
00162           double wy = (y-y0)/(y1-y0) ;
00163 
00164           /* Load all possible neighbors. */
00165           double z00 = 0.0 ;
00166           double z10 = 0.0 ;
00167           double z01 = 0.0 ;
00168           double z11 = 0.0 ;
00169 
00170           if(j > -1) {
00171             if(i > -1 ) z00 = *pt ;
00172             pt++ ;
00173             if(i < M-1) z10 = *pt ;
00174           } else {
00175             pt++ ;
00176           }
00177 
00178           pt += M - 1;
00179 
00180           if(j < N-1) {
00181             if(i > -1 ) z01 = *pt ;
00182             pt++ ;
00183             if(i < M-1) z11 = *pt ;
00184           }
00185 
00186           /* Bilinear interpolation. */
00187           z =
00188             (1 - wy) * ((1-wx) * z00 + wx * z01) +
00189             (    wy) * ((1-wx) * z10 + wx * z11) ;
00190         }
00191 
00192         *(wI_pt + jp*Mp + ip) = z ;
00193       }
00194     }
00195   }
00196 
00197   /* do also the derivatives */
00198   else {
00199 
00200     /* optimized for only image output */
00201     for(jp = 0 ; jp < Np ; ++jp) {
00202       for(ip = 0 ; ip < Mp ; ++ip) {
00203         /* Search for the four neighbors of the backprojected point. */
00204         double x = *iwXp_pt++ ;
00205         double y = *iwYp_pt++ ;
00206         double z = NaN, zx = NaN, zy = NaN ;
00207 
00208         /* This messy code allows the identity transformation
00209          * to be processed as expected. */
00210         if(x >= Xmin && x <= Xmax &&
00211            y >= Ymin && y <= Ymax) {
00212           int j = findNeighbor(x, X_pt, N) ;
00213           int i = findNeighbor(y, Y_pt, M) ;
00214           double* pt  = I_pt + j*M + i ;
00215 
00216           /* Weights. */
00217           double x0 = X_pt[j] ;
00218           double x1 = X_pt[j+1] ;
00219           double y0 = Y_pt[i] ;
00220           double y1 = Y_pt[i+1] ;
00221           double wx = (x-x0)/(x1-x0) ;
00222           double wy = (y-y0)/(y1-y0) ;
00223 
00224           /* Load all possible neighbors. */
00225           double z00 = 0.0 ;
00226           double z10 = 0.0 ;
00227           double z01 = 0.0 ;
00228           double z11 = 0.0 ;
00229 
00230           if(j > -1) {
00231             if(i > -1 ) z00 = *pt ;
00232             pt++ ;
00233             if(i < M-1) z10 = *pt ;
00234           } else {
00235             pt++ ;
00236           }
00237 
00238           pt += M - 1;
00239 
00240           if(j < N-1) {
00241             if(i > -1 ) z01 = *pt ;
00242             pt++ ;
00243             if(i < M-1) z11 = *pt ;
00244           }
00245 
00246           /* Bilinear interpolation. */
00247           z =
00248             (1-wy)*( (1-wx) * z00 + wx * z01) +
00249             wy*( (1-wx) * z10 + wx * z11) ;
00250 
00251           zx =
00252             (1-wy) * (z01 - z00) +
00253                wy  * (z11 - z10) ;
00254 
00255           zy =
00256             (1-wx) * (z10 - z00) +
00257                wx  * (z11 - z01) ;
00258         }
00259 
00260         *(wI_pt  + jp*Mp + ip) = z ;
00261         *(wIx_pt + jp*Mp + ip) = zx ;
00262         *(wIy_pt + jp*Mp + ip) = zy ;
00263       }
00264     }
00265   }
00266 }


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51