gpufilter
GPU-Efficient Recursive Filtering and Summed-Area Tables
include/cpuground.h
Go to the documentation of this file.
00001 
00009 #ifndef CPUFILTER_H
00010 #define CPUFILTER_H
00011 
00012 //== INCLUDES =================================================================
00013 
00014 #include <cmath>
00015 
00016 #include <defs.h>
00017 #include <extension.h>
00018 
00019 //== NAMESPACES ===============================================================
00020 
00021 namespace gpufilter {
00022 
00023 //== IMPLEMENTATION ===========================================================
00024 
00025 //-- Image --------------------------------------------------------------------
00026 
00044 template< class T >
00045 void extend_image( T *& ext_img,
00046                    int& ext_w,
00047                    int& ext_h,
00048                    const T *img,
00049                    const int& w,
00050                    const int& h,
00051                    const int& extb,
00052                    const initcond& ic ) {
00053     int bleft, btop, bright, bbottom;
00054     calc_borders( bleft, btop, bright, bbottom, w, h, extb );
00055     ext_w = w+bleft+bright;
00056     ext_h = h+btop+bbottom;
00057     ext_img = new float[ ext_w * ext_h ];
00058     for (int i = -btop; i < h+bbottom; ++i) {
00059         for (int j = -bleft; j < w+bright; ++j) {
00060             ext_img[(i+btop)*ext_w+(j+bleft)] = lookat(img, i, j, h, w, ic);
00061         }
00062     }
00063 }
00064 
00080 template< class T >
00081 void extract_image( T *img,
00082                     const int& w,
00083                     const int& h,
00084                     T *& ext_img,
00085                     const int& ext_w,
00086                     const int& extb ) {
00087     int bleft, btop, bright, bbottom;
00088     calc_borders( bleft, btop, bright, bbottom, w, h, extb );
00089     for (int i = 0; i < h; ++i) {
00090         for (int j = 0; j < w; ++j) {
00091             img[i*w+j] = ext_img[(i+btop)*ext_w+(j+bleft)];
00092         }
00093     }
00094     delete [] ext_img;
00095 }
00096 
00097 //-- First-order Filter -------------------------------------------------------
00098 
00119 template< class T >
00120 void rcfr( T *inout,
00121            const int& w,
00122            const int& h,
00123            const T& b0,
00124            const T& a1,
00125            const bool& ff = false ) {
00126     for (int j = 0; j < w; j++) {
00127         int i;
00128         // p=0 is not initial condition based, it is due
00129         // to the filter order outside image + extension
00130         T p = (T)0;
00131         T c;
00132         for (i = 0; i < h; i++) {
00133             c = inout[i*w+j];
00134             p = c*b0 - p*a1;
00135             inout[i*w+j] = p;
00136         }
00137         if (ff) continue;
00138         p = (T)0;
00139         for (i--; i >= 0; i--) {
00140             c = inout[i*w+j];
00141             p = c*b0 - p*a1;
00142             inout[i*w+j] = p;
00143         }
00144     }
00145 }
00146 
00167 template< class T >
00168 void rrfr( T *inout,
00169            const int& w,
00170            const int& h,
00171            const T& b0,
00172            const T& a1,
00173            const bool& ff = false ) {
00174     for (int i = 0; i < h; i++, inout += w) {
00175         int j;
00176         // p=0 is not initial condition based, it is due
00177         // to the filter order outside image + extension
00178         T p = (T)0;
00179         T c;
00180         for (j = 0; j < w; j++) {
00181             c = inout[j];
00182             p = c*b0 - p*a1;
00183             inout[j] = p;
00184         }
00185         if (ff) continue;
00186         p = (T)0;
00187         for (j--; j >= 0; j--) {
00188             c = inout[j];
00189             p = c*b0 - p*a1;
00190             inout[j] = p;
00191         }
00192     }
00193 }
00224 template< class T >
00225 void r( T *inout,
00226         const int& w,
00227         const int& h,
00228         const T& b0,
00229         const T& a1,
00230         const bool& ff = false,
00231         const int& extb = 0,
00232         const initcond& ic = zero ) {
00233     if (extend(w, h, extb)) {
00234         int ext_w, ext_h;
00235         float *ext_inout;
00236         extend_image(ext_inout, ext_w, ext_h, inout, w, h, extb, ic);
00237         rcfr(ext_inout, ext_w, ext_h, b0, a1, ff);
00238         rrfr(ext_inout, ext_w, ext_h, b0, a1, ff);
00239         extract_image(inout, w, h, ext_inout, ext_w, extb);
00240     } else {
00241         rcfr(inout, w, h, b0, a1, ff);
00242         rrfr(inout, w, h, b0, a1, ff);
00243     }
00244 }
00245 
00246 //-- Second-order Filter ------------------------------------------------------
00247 
00269 template< class T >
00270 void rcfr( T *inout,
00271            const int& w,
00272            const int& h,
00273            const T& b0,
00274            const T& a1,
00275            const T& a2,
00276            const bool& ff = false ) {
00277     for (int j = 0; j < w; j++) {
00278         int i;
00279         // pp=p=0 is not initial condition based, it is due
00280         // to the filter order outside image + extension
00281         T pp = (T)0;
00282         T p = (T)0;
00283         T c;
00284         for (i = 0; i < h; i++) {
00285             c = inout[i*w+j];
00286             c = c*b0 - p*a1 - pp*a2;
00287             pp = p;
00288             p = c;
00289             inout[i*w+j] = p;
00290         }
00291         if (ff) continue;
00292         pp = p = (T)0;
00293         for (i--; i >= 0; i--) {
00294             c = inout[i*w+j];
00295             c = c*b0 - p*a1 - pp*a2;
00296             pp = p;
00297             p = c;
00298             inout[i*w+j] = p;
00299         }
00300     }
00301 }
00302 
00324 template< class T >
00325 void rrfr( T *inout,
00326            const int& w,
00327            const int& h,
00328            const T& b0,
00329            const T& a1,
00330            const T& a2,
00331            const bool& ff = false ) {
00332     for (int i = 0; i < h; i++, inout += w) {
00333         int j;
00334         // pp=p=0 is not initial condition based, it is due
00335         // to the filter order outside image + extension
00336         T pp = (T)0;
00337         T p = (T)0;
00338         T c;
00339         for (j = 0; j < w; j++) {
00340             c = inout[j];
00341             c = c*b0 - p*a1 - pp*a2;
00342             pp = p;
00343             p = c;
00344             inout[j] = p;
00345         }
00346         if (ff) continue;
00347         pp = p = (T)0;
00348         for (j--; j >= 0; j--) {
00349             c = inout[j];
00350             c = c*b0 - p*a1 - pp*a2;
00351             pp = p;
00352             p = c;
00353             inout[j] = p;
00354         }
00355     }
00356 }
00357 
00381 template< class T >
00382 void r( T *inout,
00383         const int& w,
00384         const int& h,
00385         const T& b0,
00386         const T& a1,
00387         const T& a2,
00388         const bool& ff = false,
00389         const int& extb = 0,
00390         const initcond& ic = zero ) {
00391     if (extend(w, h, extb)) {
00392         int ext_w, ext_h;
00393         float *ext_inout;
00394         extend_image(ext_inout, ext_w, ext_h, inout, w, h, extb, ic);
00395         rcfr(ext_inout, ext_w, ext_h, b0, a1, a2, ff);
00396         rrfr(ext_inout, ext_w, ext_h, b0, a1, a2, ff);
00397         extract_image(inout, w, h, ext_inout, ext_w, extb);
00398     } else {
00399         rcfr(inout, w, h, b0, a1, a2, ff);
00400         rrfr(inout, w, h, b0, a1, a2, ff);
00401     }
00402 }
00403 
00404 //-- SAT ----------------------------------------------------------------------
00405 
00419 template< class T >
00420 void sat_cpu( T *in,
00421               const int& w,
00422               const int& h ) {
00423     r(in, w, h, (T)1, (T)-1, true);
00424 }
00434 //-- Gaussian -----------------------------------------------------------------
00435 
00453 template< class T >
00454 void gaussian_cpu( T **in,
00455                    const int& w,
00456                    const int& h,
00457                    const int& depth,
00458                    const T& s,
00459                    const int& extb = 1,
00460                    const initcond& ic = clamp ) {
00461     T b10, a11, b20, a21, a22;
00462     weights1(s, b10, a11);
00463     weights2(s, b20, a21, a22);
00464     for (int c = 0; c < depth; c++) {
00465         r(in[c], w, h, b10, a11, false, extb, ic);
00466         r(in[c], w, h, b20, a21, a22, false, extb, ic);
00467     }
00468 }
00492 template< class T >
00493 void gaussian_cpu( T *in,
00494                    const int& w,
00495                    const int& h,
00496                    const T& s,
00497                    const int& extb = 1,
00498                    const initcond& ic = clamp ) {
00499     T b10, a11, b20, a21, a22;
00500     weights1(s, b10, a11);
00501     weights2(s, b20, a21, a22);
00502     r(in, w, h, b10, a11, false, extb, ic);
00503     r(in, w, h, b20, a21, a22, false, extb, ic);
00504 }
00514 //-- BSpline ------------------------------------------------------------------
00515 
00532 template< class T >
00533 void bspline3i_cpu( T **in,
00534                     const int& w,
00535                     const int& h,
00536                     const int& depth,
00537                     const int& extb = 1,
00538                     const initcond& ic = mirror ) {
00539     const T alpha = (T)2 - sqrt((T)3);
00540     for (int c = 0; c < depth; c++) {
00541         r(in[c], w, h, (T)1+alpha, alpha, false, extb, ic);
00542     }
00543 }
00544 
00557 template< class T >
00558 void bspline3i_cpu( T *in,
00559                     const int& w,
00560                     const int& h,
00561                     const int& extb = 1,
00562                     const initcond& ic = mirror ) {
00563     const T alpha = (T)2 - sqrt((T)3);
00564     r(in, w, h, (T)1+alpha, alpha, false, extb, ic);
00565 }
00575 //=============================================================================
00576 } // namespace gpufilter
00577 //=============================================================================
00578 #endif // CPUFILTER_H
00579 //=============================================================================