gpufilter
GPU-Efficient Recursive Filtering and Summed-Area Tables
|
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 //=============================================================================