00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef __OPENCV_GPU_BORDER_INTERPOLATE_HPP__
00044 #define __OPENCV_GPU_BORDER_INTERPOLATE_HPP__
00045
00046 #include "saturate_cast.hpp"
00047 #include "vec_traits.hpp"
00048 #include "vec_math.hpp"
00049
00050 namespace cv { namespace gpu { namespace device
00051 {
00053
00054
00055 template <typename D> struct BrdRowConstant
00056 {
00057 typedef D result_type;
00058
00059 explicit __host__ __device__ __forceinline__ BrdRowConstant(int width_, const D& val_ = VecTraits<D>::all(0)) : width(width_), val(val_) {}
00060
00061 template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00062 {
00063 return x >= 0 ? saturate_cast<D>(data[x]) : val;
00064 }
00065
00066 template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00067 {
00068 return x < width ? saturate_cast<D>(data[x]) : val;
00069 }
00070
00071 template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00072 {
00073 return (x >= 0 && x < width) ? saturate_cast<D>(data[x]) : val;
00074 }
00075
00076 const int width;
00077 const D val;
00078 };
00079
00080 template <typename D> struct BrdColConstant
00081 {
00082 typedef D result_type;
00083
00084 explicit __host__ __device__ __forceinline__ BrdColConstant(int height_, const D& val_ = VecTraits<D>::all(0)) : height(height_), val(val_) {}
00085
00086 template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00087 {
00088 return y >= 0 ? saturate_cast<D>(*(const T*)((const char*)data + y * step)) : val;
00089 }
00090
00091 template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00092 {
00093 return y < height ? saturate_cast<D>(*(const T*)((const char*)data + y * step)) : val;
00094 }
00095
00096 template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00097 {
00098 return (y >= 0 && y < height) ? saturate_cast<D>(*(const T*)((const char*)data + y * step)) : val;
00099 }
00100
00101 const int height;
00102 const D val;
00103 };
00104
00105 template <typename D> struct BrdConstant
00106 {
00107 typedef D result_type;
00108
00109 __host__ __device__ __forceinline__ BrdConstant(int height_, int width_, const D& val_ = VecTraits<D>::all(0)) : height(height_), width(width_), val(val_)
00110 {
00111 }
00112
00113 template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00114 {
00115 return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast<D>(((const T*)((const uchar*)data + y * step))[x]) : val;
00116 }
00117
00118 template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00119 {
00120 return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast<D>(src(y, x)) : val;
00121 }
00122
00123 const int height;
00124 const int width;
00125 const D val;
00126 };
00127
00129
00130
00131 template <typename D> struct BrdRowReplicate
00132 {
00133 typedef D result_type;
00134
00135 explicit __host__ __device__ __forceinline__ BrdRowReplicate(int width) : last_col(width - 1) {}
00136 template <typename U> __host__ __device__ __forceinline__ BrdRowReplicate(int width, U) : last_col(width - 1) {}
00137
00138 __device__ __forceinline__ int idx_col_low(int x) const
00139 {
00140 return ::max(x, 0);
00141 }
00142
00143 __device__ __forceinline__ int idx_col_high(int x) const
00144 {
00145 return ::min(x, last_col);
00146 }
00147
00148 __device__ __forceinline__ int idx_col(int x) const
00149 {
00150 return idx_col_low(idx_col_high(x));
00151 }
00152
00153 template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00154 {
00155 return saturate_cast<D>(data[idx_col_low(x)]);
00156 }
00157
00158 template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00159 {
00160 return saturate_cast<D>(data[idx_col_high(x)]);
00161 }
00162
00163 template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00164 {
00165 return saturate_cast<D>(data[idx_col(x)]);
00166 }
00167
00168 const int last_col;
00169 };
00170
00171 template <typename D> struct BrdColReplicate
00172 {
00173 typedef D result_type;
00174
00175 explicit __host__ __device__ __forceinline__ BrdColReplicate(int height) : last_row(height - 1) {}
00176 template <typename U> __host__ __device__ __forceinline__ BrdColReplicate(int height, U) : last_row(height - 1) {}
00177
00178 __device__ __forceinline__ int idx_row_low(int y) const
00179 {
00180 return ::max(y, 0);
00181 }
00182
00183 __device__ __forceinline__ int idx_row_high(int y) const
00184 {
00185 return ::min(y, last_row);
00186 }
00187
00188 __device__ __forceinline__ int idx_row(int y) const
00189 {
00190 return idx_row_low(idx_row_high(y));
00191 }
00192
00193 template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00194 {
00195 return saturate_cast<D>(*(const T*)((const char*)data + idx_row_low(y) * step));
00196 }
00197
00198 template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00199 {
00200 return saturate_cast<D>(*(const T*)((const char*)data + idx_row_high(y) * step));
00201 }
00202
00203 template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00204 {
00205 return saturate_cast<D>(*(const T*)((const char*)data + idx_row(y) * step));
00206 }
00207
00208 const int last_row;
00209 };
00210
00211 template <typename D> struct BrdReplicate
00212 {
00213 typedef D result_type;
00214
00215 __host__ __device__ __forceinline__ BrdReplicate(int height, int width) : last_row(height - 1), last_col(width - 1) {}
00216 template <typename U> __host__ __device__ __forceinline__ BrdReplicate(int height, int width, U) : last_row(height - 1), last_col(width - 1) {}
00217
00218 __device__ __forceinline__ int idx_row_low(int y) const
00219 {
00220 return ::max(y, 0);
00221 }
00222
00223 __device__ __forceinline__ int idx_row_high(int y) const
00224 {
00225 return ::min(y, last_row);
00226 }
00227
00228 __device__ __forceinline__ int idx_row(int y) const
00229 {
00230 return idx_row_low(idx_row_high(y));
00231 }
00232
00233 __device__ __forceinline__ int idx_col_low(int x) const
00234 {
00235 return ::max(x, 0);
00236 }
00237
00238 __device__ __forceinline__ int idx_col_high(int x) const
00239 {
00240 return ::min(x, last_col);
00241 }
00242
00243 __device__ __forceinline__ int idx_col(int x) const
00244 {
00245 return idx_col_low(idx_col_high(x));
00246 }
00247
00248 template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00249 {
00250 return saturate_cast<D>(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]);
00251 }
00252
00253 template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00254 {
00255 return saturate_cast<D>(src(idx_row(y), idx_col(x)));
00256 }
00257
00258 const int last_row;
00259 const int last_col;
00260 };
00261
00263
00264
00265 template <typename D> struct BrdRowReflect101
00266 {
00267 typedef D result_type;
00268
00269 explicit __host__ __device__ __forceinline__ BrdRowReflect101(int width) : last_col(width - 1) {}
00270 template <typename U> __host__ __device__ __forceinline__ BrdRowReflect101(int width, U) : last_col(width - 1) {}
00271
00272 __device__ __forceinline__ int idx_col_low(int x) const
00273 {
00274 return ::abs(x) % (last_col + 1);
00275 }
00276
00277 __device__ __forceinline__ int idx_col_high(int x) const
00278 {
00279 return ::abs(last_col - ::abs(last_col - x)) % (last_col + 1);
00280 }
00281
00282 __device__ __forceinline__ int idx_col(int x) const
00283 {
00284 return idx_col_low(idx_col_high(x));
00285 }
00286
00287 template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00288 {
00289 return saturate_cast<D>(data[idx_col_low(x)]);
00290 }
00291
00292 template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00293 {
00294 return saturate_cast<D>(data[idx_col_high(x)]);
00295 }
00296
00297 template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00298 {
00299 return saturate_cast<D>(data[idx_col(x)]);
00300 }
00301
00302 const int last_col;
00303 };
00304
00305 template <typename D> struct BrdColReflect101
00306 {
00307 typedef D result_type;
00308
00309 explicit __host__ __device__ __forceinline__ BrdColReflect101(int height) : last_row(height - 1) {}
00310 template <typename U> __host__ __device__ __forceinline__ BrdColReflect101(int height, U) : last_row(height - 1) {}
00311
00312 __device__ __forceinline__ int idx_row_low(int y) const
00313 {
00314 return ::abs(y) % (last_row + 1);
00315 }
00316
00317 __device__ __forceinline__ int idx_row_high(int y) const
00318 {
00319 return ::abs(last_row - ::abs(last_row - y)) % (last_row + 1);
00320 }
00321
00322 __device__ __forceinline__ int idx_row(int y) const
00323 {
00324 return idx_row_low(idx_row_high(y));
00325 }
00326
00327 template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00328 {
00329 return saturate_cast<D>(*(const D*)((const char*)data + idx_row_low(y) * step));
00330 }
00331
00332 template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00333 {
00334 return saturate_cast<D>(*(const D*)((const char*)data + idx_row_high(y) * step));
00335 }
00336
00337 template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00338 {
00339 return saturate_cast<D>(*(const D*)((const char*)data + idx_row(y) * step));
00340 }
00341
00342 const int last_row;
00343 };
00344
00345 template <typename D> struct BrdReflect101
00346 {
00347 typedef D result_type;
00348
00349 __host__ __device__ __forceinline__ BrdReflect101(int height, int width) : last_row(height - 1), last_col(width - 1) {}
00350 template <typename U> __host__ __device__ __forceinline__ BrdReflect101(int height, int width, U) : last_row(height - 1), last_col(width - 1) {}
00351
00352 __device__ __forceinline__ int idx_row_low(int y) const
00353 {
00354 return ::abs(y) % (last_row + 1);
00355 }
00356
00357 __device__ __forceinline__ int idx_row_high(int y) const
00358 {
00359 return ::abs(last_row - ::abs(last_row - y)) % (last_row + 1);
00360 }
00361
00362 __device__ __forceinline__ int idx_row(int y) const
00363 {
00364 return idx_row_low(idx_row_high(y));
00365 }
00366
00367 __device__ __forceinline__ int idx_col_low(int x) const
00368 {
00369 return ::abs(x) % (last_col + 1);
00370 }
00371
00372 __device__ __forceinline__ int idx_col_high(int x) const
00373 {
00374 return ::abs(last_col - ::abs(last_col - x)) % (last_col + 1);
00375 }
00376
00377 __device__ __forceinline__ int idx_col(int x) const
00378 {
00379 return idx_col_low(idx_col_high(x));
00380 }
00381
00382 template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00383 {
00384 return saturate_cast<D>(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]);
00385 }
00386
00387 template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00388 {
00389 return saturate_cast<D>(src(idx_row(y), idx_col(x)));
00390 }
00391
00392 const int last_row;
00393 const int last_col;
00394 };
00395
00397
00398
00399 template <typename D> struct BrdRowReflect
00400 {
00401 typedef D result_type;
00402
00403 explicit __host__ __device__ __forceinline__ BrdRowReflect(int width) : last_col(width - 1) {}
00404 template <typename U> __host__ __device__ __forceinline__ BrdRowReflect(int width, U) : last_col(width - 1) {}
00405
00406 __device__ __forceinline__ int idx_col_low(int x) const
00407 {
00408 return (::abs(x) - (x < 0)) % (last_col + 1);
00409 }
00410
00411 __device__ __forceinline__ int idx_col_high(int x) const
00412 {
00413 return ::abs(last_col - ::abs(last_col - x) + (x > last_col)) % (last_col + 1);
00414 }
00415
00416 __device__ __forceinline__ int idx_col(int x) const
00417 {
00418 return idx_col_high(::abs(x) - (x < 0));
00419 }
00420
00421 template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00422 {
00423 return saturate_cast<D>(data[idx_col_low(x)]);
00424 }
00425
00426 template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00427 {
00428 return saturate_cast<D>(data[idx_col_high(x)]);
00429 }
00430
00431 template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00432 {
00433 return saturate_cast<D>(data[idx_col(x)]);
00434 }
00435
00436 const int last_col;
00437 };
00438
00439 template <typename D> struct BrdColReflect
00440 {
00441 typedef D result_type;
00442
00443 explicit __host__ __device__ __forceinline__ BrdColReflect(int height) : last_row(height - 1) {}
00444 template <typename U> __host__ __device__ __forceinline__ BrdColReflect(int height, U) : last_row(height - 1) {}
00445
00446 __device__ __forceinline__ int idx_row_low(int y) const
00447 {
00448 return (::abs(y) - (y < 0)) % (last_row + 1);
00449 }
00450
00451 __device__ __forceinline__ int idx_row_high(int y) const
00452 {
00453 return ::abs(last_row - ::abs(last_row - y) + (y > last_row)) % (last_row + 1);
00454 }
00455
00456 __device__ __forceinline__ int idx_row(int y) const
00457 {
00458 return idx_row_high(::abs(y) - (y < 0));
00459 }
00460
00461 template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00462 {
00463 return saturate_cast<D>(*(const D*)((const char*)data + idx_row_low(y) * step));
00464 }
00465
00466 template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00467 {
00468 return saturate_cast<D>(*(const D*)((const char*)data + idx_row_high(y) * step));
00469 }
00470
00471 template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00472 {
00473 return saturate_cast<D>(*(const D*)((const char*)data + idx_row(y) * step));
00474 }
00475
00476 const int last_row;
00477 };
00478
00479 template <typename D> struct BrdReflect
00480 {
00481 typedef D result_type;
00482
00483 __host__ __device__ __forceinline__ BrdReflect(int height, int width) : last_row(height - 1), last_col(width - 1) {}
00484 template <typename U> __host__ __device__ __forceinline__ BrdReflect(int height, int width, U) : last_row(height - 1), last_col(width - 1) {}
00485
00486 __device__ __forceinline__ int idx_row_low(int y) const
00487 {
00488 return (::abs(y) - (y < 0)) % (last_row + 1);
00489 }
00490
00491 __device__ __forceinline__ int idx_row_high(int y) const
00492 {
00493 return (last_row - ::abs(last_row - y) + (y > last_row)) ;
00494 }
00495
00496 __device__ __forceinline__ int idx_row(int y) const
00497 {
00498 return idx_row_low(idx_row_high(y));
00499 }
00500
00501 __device__ __forceinline__ int idx_col_low(int x) const
00502 {
00503 return (::abs(x) - (x < 0)) % (last_col + 1);
00504 }
00505
00506 __device__ __forceinline__ int idx_col_high(int x) const
00507 {
00508 return (last_col - ::abs(last_col - x) + (x > last_col));
00509 }
00510
00511 __device__ __forceinline__ int idx_col(int x) const
00512 {
00513 return idx_col_low(idx_col_high(x));
00514 }
00515
00516 template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00517 {
00518 return saturate_cast<D>(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]);
00519 }
00520
00521 template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00522 {
00523 return saturate_cast<D>(src(idx_row(y), idx_col(x)));
00524 }
00525
00526 const int last_row;
00527 const int last_col;
00528 };
00529
00531
00532
00533 template <typename D> struct BrdRowWrap
00534 {
00535 typedef D result_type;
00536
00537 explicit __host__ __device__ __forceinline__ BrdRowWrap(int width_) : width(width_) {}
00538 template <typename U> __host__ __device__ __forceinline__ BrdRowWrap(int width_, U) : width(width_) {}
00539
00540 __device__ __forceinline__ int idx_col_low(int x) const
00541 {
00542 return (x >= 0) * x + (x < 0) * (x - ((x - width + 1) / width) * width);
00543 }
00544
00545 __device__ __forceinline__ int idx_col_high(int x) const
00546 {
00547 return (x < width) * x + (x >= width) * (x % width);
00548 }
00549
00550 __device__ __forceinline__ int idx_col(int x) const
00551 {
00552 return idx_col_high(idx_col_low(x));
00553 }
00554
00555 template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00556 {
00557 return saturate_cast<D>(data[idx_col_low(x)]);
00558 }
00559
00560 template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00561 {
00562 return saturate_cast<D>(data[idx_col_high(x)]);
00563 }
00564
00565 template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00566 {
00567 return saturate_cast<D>(data[idx_col(x)]);
00568 }
00569
00570 const int width;
00571 };
00572
00573 template <typename D> struct BrdColWrap
00574 {
00575 typedef D result_type;
00576
00577 explicit __host__ __device__ __forceinline__ BrdColWrap(int height_) : height(height_) {}
00578 template <typename U> __host__ __device__ __forceinline__ BrdColWrap(int height_, U) : height(height_) {}
00579
00580 __device__ __forceinline__ int idx_row_low(int y) const
00581 {
00582 return (y >= 0) * y + (y < 0) * (y - ((y - height + 1) / height) * height);
00583 }
00584
00585 __device__ __forceinline__ int idx_row_high(int y) const
00586 {
00587 return (y < height) * y + (y >= height) * (y % height);
00588 }
00589
00590 __device__ __forceinline__ int idx_row(int y) const
00591 {
00592 return idx_row_high(idx_row_low(y));
00593 }
00594
00595 template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00596 {
00597 return saturate_cast<D>(*(const D*)((const char*)data + idx_row_low(y) * step));
00598 }
00599
00600 template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00601 {
00602 return saturate_cast<D>(*(const D*)((const char*)data + idx_row_high(y) * step));
00603 }
00604
00605 template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00606 {
00607 return saturate_cast<D>(*(const D*)((const char*)data + idx_row(y) * step));
00608 }
00609
00610 const int height;
00611 };
00612
00613 template <typename D> struct BrdWrap
00614 {
00615 typedef D result_type;
00616
00617 __host__ __device__ __forceinline__ BrdWrap(int height_, int width_) :
00618 height(height_), width(width_)
00619 {
00620 }
00621 template <typename U>
00622 __host__ __device__ __forceinline__ BrdWrap(int height_, int width_, U) :
00623 height(height_), width(width_)
00624 {
00625 }
00626
00627 __device__ __forceinline__ int idx_row_low(int y) const
00628 {
00629 return (y >= 0) * y + (y < 0) * (y - ((y - height + 1) / height) * height);
00630 }
00631
00632 __device__ __forceinline__ int idx_row_high(int y) const
00633 {
00634 return (y < height) * y + (y >= height) * (y % height);
00635 }
00636
00637 __device__ __forceinline__ int idx_row(int y) const
00638 {
00639 return idx_row_high(idx_row_low(y));
00640 }
00641
00642 __device__ __forceinline__ int idx_col_low(int x) const
00643 {
00644 return (x >= 0) * x + (x < 0) * (x - ((x - width + 1) / width) * width);
00645 }
00646
00647 __device__ __forceinline__ int idx_col_high(int x) const
00648 {
00649 return (x < width) * x + (x >= width) * (x % width);
00650 }
00651
00652 __device__ __forceinline__ int idx_col(int x) const
00653 {
00654 return idx_col_high(idx_col_low(x));
00655 }
00656
00657 template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00658 {
00659 return saturate_cast<D>(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]);
00660 }
00661
00662 template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00663 {
00664 return saturate_cast<D>(src(idx_row(y), idx_col(x)));
00665 }
00666
00667 const int height;
00668 const int width;
00669 };
00670
00672
00673
00674 template <typename Ptr2D, typename B> struct BorderReader
00675 {
00676 typedef typename B::result_type elem_type;
00677 typedef typename Ptr2D::index_type index_type;
00678
00679 __host__ __device__ __forceinline__ BorderReader(const Ptr2D& ptr_, const B& b_) : ptr(ptr_), b(b_) {}
00680
00681 __device__ __forceinline__ elem_type operator ()(index_type y, index_type x) const
00682 {
00683 return b.at(y, x, ptr);
00684 }
00685
00686 const Ptr2D ptr;
00687 const B b;
00688 };
00689
00690
00691
00692 template <typename Ptr2D, typename D> struct BorderReader< Ptr2D, BrdConstant<D> >
00693 {
00694 typedef typename BrdConstant<D>::result_type elem_type;
00695 typedef typename Ptr2D::index_type index_type;
00696
00697 __host__ __device__ __forceinline__ BorderReader(const Ptr2D& src_, const BrdConstant<D>& b) :
00698 src(src_), height(b.height), width(b.width), val(b.val)
00699 {
00700 }
00701
00702 __device__ __forceinline__ D operator ()(index_type y, index_type x) const
00703 {
00704 return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast<D>(src(y, x)) : val;
00705 }
00706
00707 const Ptr2D src;
00708 const int height;
00709 const int width;
00710 const D val;
00711 };
00712 }}}
00713
00714 #endif // __OPENCV_GPU_BORDER_INTERPOLATE_HPP__