aihot  2017-05-22 18:45:49  OpenCV |   查看评论   

实现代码remap.hpp:
  1. // fbc_cv是免费软件,并且使用与OpenCV相同的许可证
  2. #ifndef FBC_CV_REMAP_HPP_  
  3. #define FBC_CV_REMAP_HPP_  
  4.   
  5. /* reference: include/opencv2/imgproc.hpp 
  6.               modules/imgproc/src/imgwarp.cpp 
  7. */  
  8.   
  9. #include <typeinfo>  
  10. #include "core/mat.hpp"  
  11. #include "core/base.hpp"  
  12. #include "core/core.hpp"  
  13. #include "imgproc.hpp"  
  14. #include "resize.hpp"  
  15.   
  16. namespace fbc {  
  17.   
  18. const int INTER_REMAP_COEF_BITS = 15;  
  19. const int INTER_REMAP_COEF_SCALE = 1 << INTER_REMAP_COEF_BITS;  
  20.   
  21. static uchar NNDeltaTab_i[INTER_TAB_SIZE2][2];  
  22.   
  23. static float BilinearTab_f[INTER_TAB_SIZE2][2][2];  
  24. static short BilinearTab_i[INTER_TAB_SIZE2][2][2];  
  25.   
  26. static float BicubicTab_f[INTER_TAB_SIZE2][4][4];  
  27. static short BicubicTab_i[INTER_TAB_SIZE2][4][4];  
  28.   
  29. static float Lanczos4Tab_f[INTER_TAB_SIZE2][8][8];  
  30. static short Lanczos4Tab_i[INTER_TAB_SIZE2][8][8];  
  31.   
  32. template<typename _Tp1, typename _Tp2, int chs1, int chs2> static int remap_nearest(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst,  
  33.     const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2, int borderMode, const Scalar& borderValue);  
  34. template<typename _Tp1, typename _Tp2, int chs1, int chs2> static int remap_linear(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst,  
  35.     const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2, int borderMode, const Scalar& borderValue);  
  36. template<typename _Tp1, typename _Tp2, int chs1, int chs2> static int remap_cubic(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst,  
  37.     const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2, int borderMode, const Scalar& borderValue);  
  38. template<typename _Tp1, typename _Tp2, int chs1, int chs2> static int remap_lanczos4(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst,  
  39.     const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2, int borderMode, const Scalar& borderValue);  
  40.   
  41. // 对图像应用通用几何变换
  42. // 使用指定的地图转换源图像,此功能无法就地运行
  43. // 支持类型:uchar / float
  44. template<typename _Tp1, typename _Tp2, int chs1, int chs2>  
  45. int remap(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst, const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2,  
  46.     int interpolation, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar())  
  47. {  
  48.     FBC_Assert(map1.size().area() > 0 && map1.size() == map2.size());  
  49.     FBC_Assert(map1.data != NULL && map2.data != NULL);  
  50.     FBC_Assert(src.size() == map1.size() && src.size() == dst.size());  
  51.     FBC_Assert(src.data != dst.data);  
  52.     FBC_Assert(typeid(uchar).name() == typeid(_Tp1).name() || typeid(float).name() == typeid(_Tp1).name()); // uchar || float  
  53.     FBC_Assert(typeid(float).name() == typeid(_Tp2).name());  
  54.     FBC_Assert(chs2 == 1);  
  55.   
  56.     switch (interpolation) {  
  57.         case 0: {  
  58.             remap_nearest(src, dst, map1, map2, borderMode, borderValue);  
  59.             break;  
  60.         }  
  61.         case 1:  
  62.         case 3: {  
  63.             remap_linear(src, dst, map1, map2, borderMode, borderValue);  
  64.             break;  
  65.         }  
  66.         case 2: {  
  67.             remap_cubic(src, dst, map1, map2, borderMode, borderValue);  
  68.             break;  
  69.         }  
  70.         case 4: {  
  71.             remap_lanczos4(src, dst, map1, map2, borderMode, borderValue);  
  72.             break;  
  73.         }  
  74.         default:  
  75.             return -1;  
  76.     }  
  77.   
  78.     return 0;  
  79. }  
  80.   
  81. template<typename _Tp>  
  82. static inline void interpolateLinear(_Tp x, _Tp* coeffs)  
  83. {  
  84.     coeffs[0] = 1.f - x;  
  85.     coeffs[1] = x;  
  86. }  
  87.   
  88. template<typename _Tp>  
  89. static void initInterTab1D(int method, float* tab, int tabsz)  
  90. {  
  91.     float scale = 1.f / tabsz;  
  92.     if (method == INTER_LINEAR) {  
  93.         for (int i = 0; i < tabsz; i++, tab += 2)  
  94.             interpolateLinear<float>(i*scale, tab);  
  95.     } else if (method == INTER_CUBIC) {  
  96.         for (int i = 0; i < tabsz; i++, tab += 4)  
  97.             interpolateCubic<float>(i*scale, tab);  
  98.     } else if (method == INTER_LANCZOS4) {  
  99.         for (int i = 0; i < tabsz; i++, tab += 8)  
  100.             interpolateLanczos4<float>(i*scale, tab);  
  101.     } else {  
  102.         FBC_Error("Unknown interpolation method");  
  103.     }  
  104. }  
  105.   
  106. template<typename _Tp>  
  107. static const void* initInterTab2D(int method, bool fixpt)  
  108. {  
  109.     static bool inittab[INTER_MAX + 1] = { false };  
  110.     float* tab = 0;  
  111.     short* itab = 0;  
  112.     int ksize = 0;  
  113.     if (method == INTER_LINEAR) {  
  114.         tab = BilinearTab_f[0][0], itab = BilinearTab_i[0][0], ksize = 2;  
  115.     } else if (method == INTER_CUBIC) {  
  116.         tab = BicubicTab_f[0][0], itab = BicubicTab_i[0][0], ksize = 4;  
  117.     } else if (method == INTER_LANCZOS4) {  
  118.         tab = Lanczos4Tab_f[0][0], itab = Lanczos4Tab_i[0][0], ksize = 8;  
  119.     } else {  
  120.         FBC_Error("Unknown/unsupported interpolation type");  
  121.     }  
  122.   
  123.     if (!inittab[method]) {  
  124.         AutoBuffer<float> _tab(8 * INTER_TAB_SIZE);  
  125.         int i, j, k1, k2;  
  126.         initInterTab1D<float>(method, _tab, INTER_TAB_SIZE);  
  127.         for (i = 0; i < INTER_TAB_SIZE; i++) {  
  128.             for (j = 0; j < INTER_TAB_SIZE; j++, tab += ksize*ksize, itab += ksize*ksize) {  
  129.                 int isum = 0;  
  130.                 NNDeltaTab_i[i*INTER_TAB_SIZE + j][0] = j < INTER_TAB_SIZE / 2;  
  131.                 NNDeltaTab_i[i*INTER_TAB_SIZE + j][1] = i < INTER_TAB_SIZE / 2;  
  132.   
  133.                 for (k1 = 0; k1 < ksize; k1++) {  
  134.                     float vy = _tab[i*ksize + k1];  
  135.                     for (k2 = 0; k2 < ksize; k2++) {  
  136.                         float v = vy*_tab[j*ksize + k2];  
  137.                         tab[k1*ksize + k2] = v;  
  138.                         isum += itab[k1*ksize + k2] = saturate_cast<short>(v*INTER_REMAP_COEF_SCALE);  
  139.                     }  
  140.                 }  
  141.   
  142.                 if (isum != INTER_REMAP_COEF_SCALE) {  
  143.                     int diff = isum - INTER_REMAP_COEF_SCALE;  
  144.                     int ksize2 = ksize / 2, Mk1 = ksize2, Mk2 = ksize2, mk1 = ksize2, mk2 = ksize2;  
  145.                     for (k1 = ksize2; k1 < ksize2 + 2; k1++) {  
  146.                         for (k2 = ksize2; k2 < ksize2 + 2; k2++) {  
  147.                             if (itab[k1*ksize + k2] < itab[mk1*ksize + mk2])  
  148.                                 mk1 = k1, mk2 = k2;  
  149.                             else if (itab[k1*ksize + k2] > itab[Mk1*ksize + Mk2])  
  150.                                 Mk1 = k1, Mk2 = k2;  
  151.                         }  
  152.                     }  
  153.                     if (diff < 0)  
  154.                         itab[Mk1*ksize + Mk2] = (short)(itab[Mk1*ksize + Mk2] - diff);  
  155.                     else  
  156.                         itab[mk1*ksize + mk2] = (short)(itab[mk1*ksize + mk2] - diff);  
  157.                 }  
  158.             }  
  159.         }  
  160.         tab -= INTER_TAB_SIZE2*ksize*ksize;  
  161.         itab -= INTER_TAB_SIZE2*ksize*ksize;  
  162.         inittab[method] = true;  
  163.     }  
  164.   
  165.     return fixpt ? (const void*)itab : (const void*)tab;  
  166. }  
  167.   
  168. template<typename _Tp>  
  169. static bool initAllInterTab2D()  
  170. {  
  171.     return  initInterTab2D<uchar>(INTER_LINEAR, false) &&  
  172.         initInterTab2D<uchar>(INTER_LINEAR, true) &&  
  173.         initInterTab2D<uchar>(INTER_CUBIC, false) &&  
  174.         initInterTab2D<uchar>(INTER_CUBIC, true) &&  
  175.         initInterTab2D<uchar>(INTER_LANCZOS4, false) &&  
  176.         initInterTab2D<uchar>(INTER_LANCZOS4, true);  
  177. }  
  178.   
  179. static volatile bool doInitAllInterTab2D = initAllInterTab2D<uchar>();  
  180.   
  181. template<typename _Tp1, typename _Tp2, int chs1, int chs2>  
  182. static void remapNearest(const Mat_<_Tp1, chs1>& _src, Mat_<_Tp1, chs1>& _dst, const Mat_<_Tp2, chs2>& _xy, int borderType, const Scalar& _borderValue)  
  183. {  
  184.     Size ssize = _src.size(), dsize = _dst.size();  
  185.     int cn = _src.channels;  
  186.     const _Tp1* S0 = (const _Tp1*)_src.ptr();  
  187.     size_t sstep = _src.step / sizeof(S0[0]);  
  188.     Scalar_<_Tp1> cval(saturate_cast<_Tp1>(_borderValue[0]), saturate_cast<_Tp1>(_borderValue[1]), saturate_cast<_Tp1>(_borderValue[2]), saturate_cast<_Tp1>(_borderValue[3]));  
  189.     int dx, dy;  
  190.   
  191.     unsigned width1 = ssize.width, height1 = ssize.height;  
  192.   
  193.     for (dy = 0; dy < dsize.height; dy++) {  
  194.         _Tp1* D = (_Tp1*)_dst.ptr(dy);  
  195.         const short* XY = (const short*)_xy.ptr(dy);  
  196.   
  197.         if (cn == 1) {  
  198.             for (dx = 0; dx < dsize.width; dx++) {  
  199.                 int sx = XY[dx * 2], sy = XY[dx * 2 + 1];  
  200.                 if ((unsigned)sx < width1 && (unsigned)sy < height1) {  
  201.                     D[dx] = S0[sy*sstep + sx];  
  202.                 } else {  
  203.                     if (borderType == BORDER_REPLICATE) {  
  204.                         sx = clip<int>(sx, 0, ssize.width);  
  205.                         sy = clip<int>(sy, 0, ssize.height);  
  206.                         D[dx] = S0[sy*sstep + sx];  
  207.                     } else if (borderType == BORDER_CONSTANT) {  
  208.                         D[dx] = cval[0];  
  209.                     } else if (borderType != BORDER_TRANSPARENT) {  
  210.                         sx = borderInterpolate(sx, ssize.width, borderType);  
  211.                         sy = borderInterpolate(sy, ssize.height, borderType);  
  212.                         D[dx] = S0[sy*sstep + sx];  
  213.                     }  
  214.                 }  
  215.             }  
  216.         } else {  
  217.             for (dx = 0; dx < dsize.width; dx++, D += cn) {  
  218.                 int sx = XY[dx * 2], sy = XY[dx * 2 + 1], k;  
  219.                 const _Tp1 *S;  
  220.                 if ((unsigned)sx < width1 && (unsigned)sy < height1) {  
  221.                     if (cn == 3) {  
  222.                         S = S0 + sy*sstep + sx * 3;  
  223.                         D[0] = S[0], D[1] = S[1], D[2] = S[2];  
  224.                     } else if (cn == 4) {  
  225.                         S = S0 + sy*sstep + sx * 4;  
  226.                         D[0] = S[0], D[1] = S[1], D[2] = S[2], D[3] = S[3];  
  227.                     } else {  
  228.                         S = S0 + sy*sstep + sx*cn;  
  229.                         for (k = 0; k < cn; k++)  
  230.                             D[k] = S[k];  
  231.                     }  
  232.                 } else if (borderType != BORDER_TRANSPARENT) {  
  233.                     if (borderType == BORDER_REPLICATE) {  
  234.                         sx = clip<int>(sx, 0, ssize.width);  
  235.                         sy = clip<int>(sy, 0, ssize.height);  
  236.                         S = S0 + sy*sstep + sx*cn;  
  237.                     } else if (borderType == BORDER_CONSTANT) {  
  238.                         S = &cval[0];  
  239.                     } else {  
  240.                         sx = borderInterpolate(sx, ssize.width, borderType);  
  241.                         sy = borderInterpolate(sy, ssize.height, borderType);  
  242.                         S = S0 + sy*sstep + sx*cn;  
  243.                     }  
  244.                     for (k = 0; k < cn; k++)  
  245.                         D[k] = S[k];  
  246.                 }  
  247.             }  
  248.         }  
  249.     }  
  250. }  
  251.   
  252. template<class CastOp, typename AT, typename _Tp1, typename _Tp2, typename _Tp3, int chs1, int chs2, int chs3>  
  253. static int remapBilinear(const Mat_<_Tp1, chs1>& _src, Mat_<_Tp1, chs1>& _dst,  
  254.     const Mat_<_Tp2, chs2>& _xy, const Mat_<_Tp3, chs3>& _fxy, const void* _wtab, int borderType, const Scalar& _borderValue)  
  255. {  
  256.     typedef typename CastOp::rtype T;  
  257.     typedef typename CastOp::type1 WT;  
  258.     Size ssize = _src.size(), dsize = _dst.size();  
  259.     int k, cn = _src.channels;  
  260.     const AT* wtab = (const AT*)_wtab;  
  261.     const T* S0 = (const T*)_src.ptr();  
  262.     size_t sstep = _src.step / sizeof(S0[0]);  
  263.     T cval[CV_CN_MAX];  
  264.     int dx, dy;  
  265.     CastOp castOp;  
  266.   
  267.     for (k = 0; k < cn; k++)  
  268.         cval[k] = saturate_cast<T>(_borderValue[k & 3]);  
  269.   
  270.     unsigned width1 = std::max(ssize.width - 1, 0), height1 = std::max(ssize.height - 1, 0);  
  271.     FBC_Assert(ssize.area() > 0);  
  272.   
  273.     for (dy = 0; dy < dsize.height; dy++) {  
  274.         T* D = (T*)_dst.ptr(dy);  
  275.         const short* XY = (const short*)_xy.ptr(dy);  
  276.         const ushort* FXY = (const ushort*)_fxy.ptr(dy);  
  277.         int X0 = 0;  
  278.         bool prevInlier = false;  
  279.   
  280.         for (dx = 0; dx <= dsize.width; dx++) {  
  281.             bool curInlier = dx < dsize.width ? (unsigned)XY[dx * 2] < width1 && (unsigned)XY[dx * 2 + 1] < height1 : !prevInlier;  
  282.             if (curInlier == prevInlier)  
  283.                 continue;  
  284.   
  285.             int X1 = dx;  
  286.             dx = X0;  
  287.             X0 = X1;  
  288.             prevInlier = curInlier;  
  289.   
  290.             if (!curInlier) {  
  291.                 int len = 0;  
  292.                 D += len*cn;  
  293.                 dx += len;  
  294.   
  295.                 if (cn == 1) {  
  296.                     for (; dx < X1; dx++, D++) {  
  297.                         int sx = XY[dx * 2], sy = XY[dx * 2 + 1];  
  298.                         const AT* w = wtab + FXY[dx] * 4;  
  299.                         const T* S = S0 + sy*sstep + sx;  
  300.                         *D = castOp(WT(S[0] * w[0] + S[1] * w[1] + S[sstep] * w[2] + S[sstep + 1] * w[3]));  
  301.                     }  
  302.                 } else if (cn == 2) {  
  303.                     for (; dx < X1; dx++, D += 2) {  
  304.                         int sx = XY[dx * 2], sy = XY[dx * 2 + 1];  
  305.                         const AT* w = wtab + FXY[dx] * 4;  
  306.                         const T* S = S0 + sy*sstep + sx * 2;  
  307.                         WT t0 = S[0] * w[0] + S[2] * w[1] + S[sstep] * w[2] + S[sstep + 2] * w[3];  
  308.                         WT t1 = S[1] * w[0] + S[3] * w[1] + S[sstep + 1] * w[2] + S[sstep + 3] * w[3];  
  309.                         D[0] = castOp(t0); D[1] = castOp(t1);  
  310.                     }  
  311.                 } else if (cn == 3) {  
  312.                     for (; dx < X1; dx++, D += 3) {  
  313.                         int sx = XY[dx * 2], sy = XY[dx * 2 + 1];  
  314.                         const AT* w = wtab + FXY[dx] * 4;  
  315.                         const T* S = S0 + sy*sstep + sx * 3;  
  316.                         WT t0 = S[0] * w[0] + S[3] * w[1] + S[sstep] * w[2] + S[sstep + 3] * w[3];  
  317.                         WT t1 = S[1] * w[0] + S[4] * w[1] + S[sstep + 1] * w[2] + S[sstep + 4] * w[3];  
  318.                         WT t2 = S[2] * w[0] + S[5] * w[1] + S[sstep + 2] * w[2] + S[sstep + 5] * w[3];  
  319.                         D[0] = castOp(t0); D[1] = castOp(t1); D[2] = castOp(t2);  
  320.                     }  
  321.                 } else if (cn == 4) {  
  322.                     for (; dx < X1; dx++, D += 4) {  
  323.                         int sx = XY[dx * 2], sy = XY[dx * 2 + 1];  
  324.                         const AT* w = wtab + FXY[dx] * 4;  
  325.                         const T* S = S0 + sy*sstep + sx * 4;  
  326.                         WT t0 = S[0] * w[0] + S[4] * w[1] + S[sstep] * w[2] + S[sstep + 4] * w[3];  
  327.                         WT t1 = S[1] * w[0] + S[5] * w[1] + S[sstep + 1] * w[2] + S[sstep + 5] * w[3];  
  328.                         D[0] = castOp(t0); D[1] = castOp(t1);  
  329.                         t0 = S[2] * w[0] + S[6] * w[1] + S[sstep + 2] * w[2] + S[sstep + 6] * w[3];  
  330.                         t1 = S[3] * w[0] + S[7] * w[1] + S[sstep + 3] * w[2] + S[sstep + 7] * w[3];  
  331.                         D[2] = castOp(t0); D[3] = castOp(t1);  
  332.                     }  
  333.                 } else {  
  334.                     for (; dx < X1; dx++, D += cn) {  
  335.                         int sx = XY[dx * 2], sy = XY[dx * 2 + 1];  
  336.                         const AT* w = wtab + FXY[dx] * 4;  
  337.                         const T* S = S0 + sy*sstep + sx*cn;  
  338.                         for (k = 0; k < cn; k++) {  
  339.                             WT t0 = S[k] * w[0] + S[k + cn] * w[1] + S[sstep + k] * w[2] + S[sstep + k + cn] * w[3];  
  340.                             D[k] = castOp(t0);  
  341.                         }  
  342.                     }  
  343.                 }  
  344.             } else {  
  345.                 if (borderType == BORDER_TRANSPARENT && cn != 3) {  
  346.                     D += (X1 - dx)*cn;  
  347.                     dx = X1;  
  348.                     continue;  
  349.                 }  
  350.   
  351.                 if (cn == 1) {  
  352.                     for (; dx < X1; dx++, D++) {  
  353.                         int sx = XY[dx * 2], sy = XY[dx * 2 + 1];  
  354.                         if (borderType == BORDER_CONSTANT && (sx >= ssize.width || sx + 1 < 0 || sy >= ssize.height || sy + 1 < 0)) {  
  355.                             D[0] = cval[0];  
  356.                         } else {  
  357.                             int sx0, sx1, sy0, sy1;  
  358.                             T v0, v1, v2, v3;  
  359.                             const AT* w = wtab + FXY[dx] * 4;  
  360.                             if (borderType == BORDER_REPLICATE) {  
  361.                                 sx0 = clip(sx, 0, ssize.width);  
  362.                                 sx1 = clip(sx + 1, 0, ssize.width);  
  363.                                 sy0 = clip(sy, 0, ssize.height);  
  364.                                 sy1 = clip(sy + 1, 0, ssize.height);  
  365.                                 v0 = S0[sy0*sstep + sx0];  
  366.                                 v1 = S0[sy0*sstep + sx1];  
  367.                                 v2 = S0[sy1*sstep + sx0];  
  368.                                 v3 = S0[sy1*sstep + sx1];  
  369.                             } else {  
  370.                                 sx0 = borderInterpolate(sx, ssize.width, borderType);  
  371.                                 sx1 = borderInterpolate(sx + 1, ssize.width, borderType);  
  372.                                 sy0 = borderInterpolate(sy, ssize.height, borderType);  
  373.                                 sy1 = borderInterpolate(sy + 1, ssize.height, borderType);  
  374.                                 v0 = sx0 >= 0 && sy0 >= 0 ? S0[sy0*sstep + sx0] : cval[0];  
  375.                                 v1 = sx1 >= 0 && sy0 >= 0 ? S0[sy0*sstep + sx1] : cval[0];  
  376.                                 v2 = sx0 >= 0 && sy1 >= 0 ? S0[sy1*sstep + sx0] : cval[0];  
  377.                                 v3 = sx1 >= 0 && sy1 >= 0 ? S0[sy1*sstep + sx1] : cval[0];  
  378.                             }  
  379.                             D[0] = castOp(WT(v0*w[0] + v1*w[1] + v2*w[2] + v3*w[3]));  
  380.                         }  
  381.                     }  
  382.                 } else {  
  383.                     for (; dx < X1; dx++, D += cn) {  
  384.                         int sx = XY[dx * 2], sy = XY[dx * 2 + 1];  
  385.                         if (borderType == BORDER_CONSTANT && (sx >= ssize.width || sx + 1 < 0 || sy >= ssize.height || sy + 1 < 0)) {  
  386.                             for (k = 0; k < cn; k++)  
  387.                                 D[k] = cval[k];  
  388.                         } else {  
  389.                             int sx0, sx1, sy0, sy1;  
  390.                             const T *v0, *v1, *v2, *v3;  
  391.                             const AT* w = wtab + FXY[dx] * 4;  
  392.                             if (borderType == BORDER_REPLICATE) {  
  393.                                 sx0 = clip(sx, 0, ssize.width);  
  394.                                 sx1 = clip(sx + 1, 0, ssize.width);  
  395.                                 sy0 = clip(sy, 0, ssize.height);  
  396.                                 sy1 = clip(sy + 1, 0, ssize.height);  
  397.                                 v0 = S0 + sy0*sstep + sx0*cn;  
  398.                                 v1 = S0 + sy0*sstep + sx1*cn;  
  399.                                 v2 = S0 + sy1*sstep + sx0*cn;  
  400.                                 v3 = S0 + sy1*sstep + sx1*cn;  
  401.                             } else if (borderType == BORDER_TRANSPARENT && ((unsigned)sx >= (unsigned)(ssize.width - 1) || (unsigned)sy >= (unsigned)(ssize.height - 1))) {  
  402.                                 continue;  
  403.                             } else {  
  404.                                 sx0 = borderInterpolate(sx, ssize.width, borderType);  
  405.                                 sx1 = borderInterpolate(sx + 1, ssize.width, borderType);  
  406.                                 sy0 = borderInterpolate(sy, ssize.height, borderType);  
  407.                                 sy1 = borderInterpolate(sy + 1, ssize.height, borderType);  
  408.                                 v0 = sx0 >= 0 && sy0 >= 0 ? S0 + sy0*sstep + sx0*cn : &cval[0];  
  409.                                 v1 = sx1 >= 0 && sy0 >= 0 ? S0 + sy0*sstep + sx1*cn : &cval[0];  
  410.                                 v2 = sx0 >= 0 && sy1 >= 0 ? S0 + sy1*sstep + sx0*cn : &cval[0];  
  411.                                 v3 = sx1 >= 0 && sy1 >= 0 ? S0 + sy1*sstep + sx1*cn : &cval[0];  
  412.                             }  
  413.                             for (k = 0; k < cn; k++)  
  414.                                 D[k] = castOp(WT(v0[k] * w[0] + v1[k] * w[1] + v2[k] * w[2] + v3[k] * w[3]));  
  415.                         }  
  416.                     }  
  417.                 }  
  418.             }  
  419.         }  
  420.     }  
  421.   
  422.     return 0;  
  423. }  
  424.   
  425. template<class CastOp, typename AT, int ONE, typename _Tp1, typename _Tp2, typename _Tp3, int chs1, int chs2, int chs3>  
  426. static int remapBicubic(const Mat_<_Tp1, chs1>& _src, Mat_<_Tp1, chs1>& _dst,  
  427.     const Mat_<_Tp2, chs2>& _xy, const Mat_<_Tp3, chs3>& _fxy, const void* _wtab, int borderType, const Scalar& _borderValue)  
  428. {  
  429.     typedef typename CastOp::rtype T;  
  430.     typedef typename CastOp::type1 WT;  
  431.     Size ssize = _src.size(), dsize = _dst.size();  
  432.     int cn = _src.channels;  
  433.     const AT* wtab = (const AT*)_wtab;  
  434.     const T* S0 = (const T*)_src.ptr();  
  435.     size_t sstep = _src.step / sizeof(S0[0]);  
  436.     Scalar_<T> cval(saturate_cast<T>(_borderValue[0]),  
  437.         saturate_cast<T>(_borderValue[1]),  
  438.         saturate_cast<T>(_borderValue[2]),  
  439.         saturate_cast<T>(_borderValue[3]));  
  440.     int dx, dy;  
  441.     CastOp castOp;  
  442.     int borderType1 = borderType != BORDER_TRANSPARENT ? borderType : BORDER_REFLECT_101;  
  443.   
  444.     unsigned width1 = std::max(ssize.width - 3, 0), height1 = std::max(ssize.height - 3, 0);  
  445.   
  446.     for (dy = 0; dy < dsize.height; dy++) {  
  447.         T* D = (T*)_dst.ptr(dy);  
  448.         const short* XY = (const short*)_xy.ptr(dy);  
  449.         const ushort* FXY = (const ushort*)_fxy.ptr(dy);  
  450.   
  451.         for (dx = 0; dx < dsize.width; dx++, D += cn) {  
  452.             int sx = XY[dx * 2] - 1, sy = XY[dx * 2 + 1] - 1;  
  453.             const AT* w = wtab + FXY[dx] * 16;  
  454.             int i, k;  
  455.             if ((unsigned)sx < width1 && (unsigned)sy < height1) {  
  456.                 const T* S = S0 + sy*sstep + sx*cn;  
  457.                 for (k = 0; k < cn; k++) {  
  458.                     WT sum = S[0] * w[0] + S[cn] * w[1] + S[cn * 2] * w[2] + S[cn * 3] * w[3];  
  459.                     S += sstep;  
  460.                     sum += S[0] * w[4] + S[cn] * w[5] + S[cn * 2] * w[6] + S[cn * 3] * w[7];  
  461.                     S += sstep;  
  462.                     sum += S[0] * w[8] + S[cn] * w[9] + S[cn * 2] * w[10] + S[cn * 3] * w[11];  
  463.                     S += sstep;  
  464.                     sum += S[0] * w[12] + S[cn] * w[13] + S[cn * 2] * w[14] + S[cn * 3] * w[15];  
  465.                     S += 1 - sstep * 3;  
  466.                     D[k] = castOp(sum);  
  467.                 }  
  468.             } else {  
  469.                 int x[4], y[4];  
  470.                 if (borderType == BORDER_TRANSPARENT &&  
  471.                     ((unsigned)(sx + 1) >= (unsigned)ssize.width ||  
  472.                     (unsigned)(sy + 1) >= (unsigned)ssize.height))  
  473.                     continue;  
  474.   
  475.                 if (borderType1 == BORDER_CONSTANT &&  
  476.                     (sx >= ssize.width || sx + 4 <= 0 ||  
  477.                     sy >= ssize.height || sy + 4 <= 0)) {  
  478.                     for (k = 0; k < cn; k++)  
  479.                         D[k] = cval[k];  
  480.                     continue;  
  481.                 }  
  482.   
  483.                 for (i = 0; i < 4; i++) {  
  484.                     x[i] = borderInterpolate(sx + i, ssize.width, borderType1)*cn;  
  485.                     y[i] = borderInterpolate(sy + i, ssize.height, borderType1);  
  486.                 }  
  487.   
  488.                 for (k = 0; k < cn; k++, S0++, w -= 16) {  
  489.                     WT cv = cval[k], sum = cv*ONE;  
  490.                     for (i = 0; i < 4; i++, w += 4) {  
  491.                         int yi = y[i];  
  492.                         const T* S = S0 + yi*sstep;  
  493.                         if (yi < 0)  
  494.                             continue;  
  495.                         if (x[0] >= 0)  
  496.                             sum += (S[x[0]] - cv)*w[0];  
  497.                         if (x[1] >= 0)  
  498.                             sum += (S[x[1]] - cv)*w[1];  
  499.                         if (x[2] >= 0)  
  500.                             sum += (S[x[2]] - cv)*w[2];  
  501.                         if (x[3] >= 0)  
  502.                             sum += (S[x[3]] - cv)*w[3];  
  503.                     }  
  504.                     D[k] = castOp(sum);  
  505.                 }  
  506.                 S0 -= cn;  
  507.             }  
  508.         }  
  509.     }  
  510.   
  511.     return 0;  
  512. }  
  513.   
  514. template<class CastOp, typename AT, int ONE, typename _Tp1, typename _Tp2, typename _Tp3, int chs1, int chs2, int chs3>  
  515. static int remapLanczos4(const Mat_<_Tp1, chs1>& _src, Mat_<_Tp1, chs1>& _dst,  
  516.     const Mat_<_Tp2, chs2>& _xy, const Mat_<_Tp3, chs3>& _fxy, const void* _wtab, int borderType, const Scalar& _borderValue)  
  517. {  
  518.     typedef typename CastOp::rtype T;  
  519.     typedef typename CastOp::type1 WT;  
  520.     Size ssize = _src.size(), dsize = _dst.size();  
  521.     int cn = _src.channels;  
  522.     const AT* wtab = (const AT*)_wtab;  
  523.     const T* S0 = (const T*)_src.ptr();  
  524.     size_t sstep = _src.step / sizeof(S0[0]);  
  525.     Scalar_<T> cval(saturate_cast<T>(_borderValue[0]),  
  526.         saturate_cast<T>(_borderValue[1]),  
  527.         saturate_cast<T>(_borderValue[2]),  
  528.         saturate_cast<T>(_borderValue[3]));  
  529.     int dx, dy;  
  530.     CastOp castOp;  
  531.     int borderType1 = borderType != BORDER_TRANSPARENT ? borderType : BORDER_REFLECT_101;  
  532.   
  533.     unsigned width1 = std::max(ssize.width - 7, 0), height1 = std::max(ssize.height - 7, 0);  
  534.   
  535.     for (dy = 0; dy < dsize.height; dy++) {  
  536.         T* D = (T*)_dst.ptr(dy);  
  537.         const short* XY = (const short*)_xy.ptr(dy);  
  538.         const ushort* FXY = (const ushort*)_fxy.ptr(dy);  
  539.   
  540.         for (dx = 0; dx < dsize.width; dx++, D += cn) {  
  541.             int sx = XY[dx * 2] - 3, sy = XY[dx * 2 + 1] - 3;  
  542.             const AT* w = wtab + FXY[dx] * 64;  
  543.             const T* S = S0 + sy*sstep + sx*cn;  
  544.             int i, k;  
  545.             if ((unsigned)sx < width1 && (unsigned)sy < height1) {  
  546.                 for (k = 0; k < cn; k++) {  
  547.                     WT sum = 0;  
  548.                     for (int r = 0; r < 8; r++, S += sstep, w += 8)  
  549.                         sum += S[0] * w[0] + S[cn] * w[1] + S[cn * 2] * w[2] + S[cn * 3] * w[3] +  
  550.                         S[cn * 4] * w[4] + S[cn * 5] * w[5] + S[cn * 6] * w[6] + S[cn * 7] * w[7];  
  551.                     w -= 64;  
  552.                     S -= sstep * 8 - 1;  
  553.                     D[k] = castOp(sum);  
  554.                 }  
  555.             } else {  
  556.                 int x[8], y[8];  
  557.                 if (borderType == BORDER_TRANSPARENT &&  
  558.                     ((unsigned)(sx + 3) >= (unsigned)ssize.width ||  
  559.                     (unsigned)(sy + 3) >= (unsigned)ssize.height))  
  560.                     continue;  
  561.   
  562.                 if (borderType1 == BORDER_CONSTANT &&  
  563.                     (sx >= ssize.width || sx + 8 <= 0 ||  
  564.                     sy >= ssize.height || sy + 8 <= 0)) {  
  565.                     for (k = 0; k < cn; k++)  
  566.                         D[k] = cval[k];  
  567.                     continue;  
  568.                 }  
  569.   
  570.                 for (i = 0; i < 8; i++) {  
  571.                     x[i] = borderInterpolate(sx + i, ssize.width, borderType1)*cn;  
  572.                     y[i] = borderInterpolate(sy + i, ssize.height, borderType1);  
  573.                 }  
  574.   
  575.                 for (k = 0; k < cn; k++, S0++, w -= 64) {  
  576.                     WT cv = cval[k], sum = cv*ONE;  
  577.                     for (i = 0; i < 8; i++, w += 8) {  
  578.                         int yi = y[i];  
  579.                         const T* S1 = S0 + yi*sstep;  
  580.                         if (yi < 0)  
  581.                             continue;  
  582.                         if (x[0] >= 0)  
  583.                             sum += (S1[x[0]] - cv)*w[0];  
  584.                         if (x[1] >= 0)  
  585.                             sum += (S1[x[1]] - cv)*w[1];  
  586.                         if (x[2] >= 0)  
  587.                             sum += (S1[x[2]] - cv)*w[2];  
  588.                         if (x[3] >= 0)  
  589.                             sum += (S1[x[3]] - cv)*w[3];  
  590.                         if (x[4] >= 0)  
  591.                             sum += (S1[x[4]] - cv)*w[4];  
  592.                         if (x[5] >= 0)  
  593.                             sum += (S1[x[5]] - cv)*w[5];  
  594.                         if (x[6] >= 0)  
  595.                             sum += (S1[x[6]] - cv)*w[6];  
  596.                         if (x[7] >= 0)  
  597.                             sum += (S1[x[7]] - cv)*w[7];  
  598.                     }  
  599.                     D[k] = castOp(sum);  
  600.                 }  
  601.                 S0 -= cn;  
  602.             }  
  603.         }  
  604.     }  
  605.   
  606.     return 0;  
  607. }  
  608.   
  609. template<typename _Tp1, typename _Tp2, int chs1, int chs2>  
  610. static int remap_nearest(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst,  
  611.     const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2, int borderMode, const Scalar& borderValue)  
  612. {  
  613.     const void* ctab = 0;  
  614.     bool fixpt = typeid(uchar).name() == typeid(_Tp1).name();  
  615.     bool planar_input = map1.channels == 1;  
  616.     Range range(0, dst.rows);  
  617.   
  618.     int x, y, x1, y1;  
  619.     const int buf_size = 1 << 14;  
  620.     int brows0 = std::min(128, dst.rows);  
  621.     int bcols0 = std::min(buf_size / brows0, dst.cols);  
  622.     brows0 = std::min(buf_size / bcols0, dst.rows);  
  623.   
  624.     Mat_<short, 2> _bufxy(brows0, bcols0);  
  625.   
  626.     for (y = range.start; y < range.end; y += brows0) {  
  627.         for (x = 0; x < dst.cols; x += bcols0) {  
  628.             int brows = std::min(brows0, range.end - y);  
  629.             int bcols = std::min(bcols0, dst.cols - x);  
  630.             Mat_<_Tp1, chs1> dpart;  
  631.             dst.getROI(dpart, Rect(x, y, bcols, brows));  
  632.             Mat_<short, 2> bufxy;  
  633.             _bufxy.getROI(bufxy, Rect(0, 0, bcols, brows));  
  634.   
  635.             if (sizeof(_Tp2) == sizeof(short)) { // short  
  636.                 for (y1 = 0; y1 < brows; y1++) {  
  637.                     short* XY = (short*)bufxy.ptr(y1);  
  638.                     const short* sXY = (const short*)map1.ptr(y + y1) + x * 2;  
  639.                     const ushort* sA = (const ushort*)map2.ptr(y + y1) + x;  
  640.   
  641.                     for (x1 = 0; x1 < bcols; x1++) {  
  642.                         int a = sA[x1] & (INTER_TAB_SIZE2 - 1);  
  643.                         XY[x1 * 2] = sXY[x1 * 2] + NNDeltaTab_i[a][0];  
  644.                         XY[x1 * 2 + 1] = sXY[x1 * 2 + 1] + NNDeltaTab_i[a][1];  
  645.                     }  
  646.                 }  
  647.             } else { // float  
  648.                 for (y1 = 0; y1 < brows; y1++) {  
  649.                     short* XY = (short*)bufxy.ptr(y1);  
  650.                     const float* sX = (const float*)map1.ptr(y + y1) + x;  
  651.                     const float* sY = (const float*)map2.ptr(y + y1) + x;  
  652.   
  653.                     x1 = 0;  
  654.                     for (; x1 < bcols; x1++) {  
  655.                         XY[x1 * 2] = saturate_cast<short>(sX[x1]);  
  656.                         XY[x1 * 2 + 1] = saturate_cast<short>(sY[x1]);  
  657.                     }  
  658.                 }  
  659.             }  
  660.   
  661.             remapNearest<_Tp1, short, chs1, 2>(src, dpart, bufxy, borderMode, borderValue);  
  662.         }  
  663.     }  
  664.   
  665.     return 0;  
  666. }  
  667.   
  668. template<typename _Tp1, typename _Tp2, int chs1, int chs2>  
  669. static int remap_linear(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst,  
  670.     const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2, int borderMode, const Scalar& borderValue)  
  671. {  
  672.     const void* ctab = 0;  
  673.     bool fixpt = typeid(uchar).name() == typeid(_Tp1).name();  
  674.     bool planar_input = map1.channels == 1;  
  675.     ctab = initInterTab2D<_Tp1>(INTER_LINEAR, fixpt);  
  676.     Range range(0, dst.rows);  
  677.   
  678.     int x, y, x1, y1;  
  679.     const int buf_size = 1 << 14;  
  680.     int brows0 = std::min(128, dst.rows);  
  681.     int bcols0 = std::min(buf_size / brows0, dst.cols);  
  682.     brows0 = std::min(buf_size / bcols0, dst.rows);  
  683.   
  684.     Mat_<short, 2> _bufxy(brows0, bcols0);  
  685.     Mat_<ushort, 1> _bufa(brows0, bcols0);  
  686.   
  687.     for (y = range.start; y < range.end; y += brows0) {  
  688.         for (x = 0; x < dst.cols; x += bcols0) {  
  689.             int brows = std::min(brows0, range.end - y);  
  690.             int bcols = std::min(bcols0, dst.cols - x);  
  691.             Mat_<_Tp1, chs1> dpart;  
  692.             dst.getROI(dpart, Rect(x, y, bcols, brows));  
  693.             Mat_<short, 2> bufxy;  
  694.             _bufxy.getROI(bufxy, Rect(0, 0, bcols, brows));  
  695.             Mat_<ushort, 1> bufa;  
  696.             _bufa.getROI(bufa, Rect(0, 0, bcols, brows));  
  697.   
  698.             for (y1 = 0; y1 < brows; y1++) {  
  699.                 short* XY = (short*)bufxy.ptr(y1);  
  700.                 ushort* A = (ushort*)bufa.ptr(y1);  
  701.   
  702.                 if (planar_input) {  
  703.                     const float* sX = (const float*)map1.ptr(y + y1) + x;  
  704.                     const float* sY = (const float*)map2.ptr(y + y1) + x;  
  705.   
  706.                     x1 = 0;  
  707.                     for (; x1 < bcols; x1++) {  
  708.                         int sx = fbcRound(sX[x1] * INTER_TAB_SIZE);  
  709.                         int sy = fbcRound(sY[x1] * INTER_TAB_SIZE);  
  710.                         int v = (sy & (INTER_TAB_SIZE - 1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE - 1));  
  711.                         XY[x1 * 2] = saturate_cast<short>(sx >> INTER_BITS);  
  712.                         XY[x1 * 2 + 1] = saturate_cast<short>(sy >> INTER_BITS);  
  713.                         A[x1] = (ushort)v;  
  714.                     }  
  715.                 } else {  
  716.                     const float* sXY = (const float*)map1.ptr(y + y1) + x * 2;  
  717.                     x1 = 0;  
  718.                     for (x1 = 0; x1 < bcols; x1++) {  
  719.                         int sx = fbcRound(sXY[x1 * 2] * INTER_TAB_SIZE);  
  720.                         int sy = fbcRound(sXY[x1 * 2 + 1] * INTER_TAB_SIZE);  
  721.                         int v = (sy & (INTER_TAB_SIZE - 1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE - 1));  
  722.                         XY[x1 * 2] = saturate_cast<short>(sx >> INTER_BITS);  
  723.                         XY[x1 * 2 + 1] = saturate_cast<short>(sy >> INTER_BITS);  
  724.                         A[x1] = (ushort)v;  
  725.                     }  
  726.                 }  
  727.             }  
  728.   
  729.             if (typeid(_Tp1).name() == typeid(uchar).name()) { // uchar  
  730.                 remapBilinear<FixedPtCast<int, uchar, INTER_REMAP_COEF_BITS>, short, _Tp1, short, ushort, chs1, 2, 1>(src, dpart, bufxy, bufa, ctab, borderMode, borderValue);  
  731.             } else { // float  
  732.                 remapBilinear<Cast<floatfloat>, float, _Tp1, short, ushort, chs1, 2, 1>(src, dpart, bufxy, bufa, ctab, borderMode, borderValue);  
  733.             }  
  734.         }  
  735.     }  
  736.   
  737.     return 0;  
  738. }  
  739.   
  740. template<typename _Tp1, typename _Tp2, int chs1, int chs2>  
  741. static int remap_cubic(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst,  
  742.     const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2, int borderMode, const Scalar& borderValue)  
  743. {  
  744.     const void* ctab = 0;  
  745.     bool fixpt = typeid(uchar).name() == typeid(_Tp1).name();  
  746.     bool planar_input = map1.channels == 1;  
  747.     ctab = initInterTab2D<_Tp1>(INTER_CUBIC, fixpt);  
  748.     Range range(0, dst.rows);  
  749.   
  750.     int x, y, x1, y1;  
  751.     const int buf_size = 1 << 14;  
  752.     int brows0 = std::min(128, dst.rows);  
  753.     int bcols0 = std::min(buf_size / brows0, dst.cols);  
  754.     brows0 = std::min(buf_size / bcols0, dst.rows);  
  755.   
  756.     Mat_<short, 2> _bufxy(brows0, bcols0);  
  757.     Mat_<ushort, 1> _bufa(brows0, bcols0);  
  758.   
  759.     for (y = range.start; y < range.end; y += brows0) {  
  760.         for (x = 0; x < dst.cols; x += bcols0) {  
  761.             int brows = std::min(brows0, range.end - y);  
  762.             int bcols = std::min(bcols0, dst.cols - x);  
  763.             Mat_<_Tp1, chs1> dpart;  
  764.             dst.getROI(dpart, Rect(x, y, bcols, brows));  
  765.             Mat_<short, 2> bufxy;  
  766.             _bufxy.getROI(bufxy, Rect(0, 0, bcols, brows));  
  767.             Mat_<ushort, 1> bufa;  
  768.             _bufa.getROI(bufa, Rect(0, 0, bcols, brows));  
  769.   
  770.             for (y1 = 0; y1 < brows; y1++) {  
  771.                 short* XY = (short*)bufxy.ptr(y1);  
  772.                 ushort* A = (ushort*)bufa.ptr(y1);  
  773.   
  774.                 if (planar_input) {  
  775.                     const float* sX = (const float*)map1.ptr(y + y1) + x;  
  776.                     const float* sY = (const float*)map2.ptr(y + y1) + x;  
  777.   
  778.                     x1 = 0;  
  779.                     for (; x1 < bcols; x1++) {  
  780.                         int sx = fbcRound(sX[x1] * INTER_TAB_SIZE);  
  781.                         int sy = fbcRound(sY[x1] * INTER_TAB_SIZE);  
  782.                         int v = (sy & (INTER_TAB_SIZE - 1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE - 1));  
  783.                         XY[x1 * 2] = saturate_cast<short>(sx >> INTER_BITS);  
  784.                         XY[x1 * 2 + 1] = saturate_cast<short>(sy >> INTER_BITS);  
  785.                         A[x1] = (ushort)v;  
  786.                     }  
  787.                 } else {  
  788.                     const float* sXY = (const float*)map1.ptr(y + y1) + x * 2;  
  789.                     x1 = 0;  
  790.                     for (x1 = 0; x1 < bcols; x1++) {  
  791.                         int sx = fbcRound(sXY[x1 * 2] * INTER_TAB_SIZE);  
  792.                         int sy = fbcRound(sXY[x1 * 2 + 1] * INTER_TAB_SIZE);  
  793.                         int v = (sy & (INTER_TAB_SIZE - 1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE - 1));  
  794.                         XY[x1 * 2] = saturate_cast<short>(sx >> INTER_BITS);  
  795.                         XY[x1 * 2 + 1] = saturate_cast<short>(sy >> INTER_BITS);  
  796.                         A[x1] = (ushort)v;  
  797.                     }  
  798.                 }  
  799.             }  
  800.   
  801.             if (typeid(_Tp1).name() == typeid(uchar).name()) { // uchar  
  802.                 remapBicubic<FixedPtCast<int, uchar, INTER_REMAP_COEF_BITS>, short, INTER_REMAP_COEF_SCALE, _Tp1, short, ushort, chs1, 2, 1>(src, dpart, bufxy, bufa, ctab, borderMode, borderValue);  
  803.             } else { // float  
  804.                 remapBicubic<Cast<floatfloat>, float, 1, _Tp1, short, ushort, chs1, 2, 1>(src, dpart, bufxy, bufa, ctab, borderMode, borderValue);  
  805.             }  
  806.         }  
  807.     }  
  808.   
  809.     return 0;  
  810. }  
  811.   
  812. template<typename _Tp1, typename _Tp2, int chs1, int chs2>  
  813. static int remap_lanczos4(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst,  
  814.     const Mat_<_Tp2, chs2>& map1, const Mat_<_Tp2, chs2>& map2, int borderMode, const Scalar& borderValue)  
  815. {  
  816.     const void* ctab = 0;  
  817.     bool fixpt = typeid(uchar).name() == typeid(_Tp1).name();  
  818.     bool planar_input = map1.channels == 1;  
  819.     ctab = initInterTab2D<_Tp1>(INTER_LANCZOS4, fixpt);  
  820.     Range range(0, dst.rows);  
  821.   
  822.     int x, y, x1, y1;  
  823.     const int buf_size = 1 << 14;  
  824.     int brows0 = std::min(128, dst.rows);  
  825.     int bcols0 = std::min(buf_size / brows0, dst.cols);  
  826.     brows0 = std::min(buf_size / bcols0, dst.rows);  
  827.   
  828.     Mat_<short, 2> _bufxy(brows0, bcols0);  
  829.     Mat_<ushort, 1> _bufa(brows0, bcols0);  
  830.   
  831.     for (y = range.start; y < range.end; y += brows0) {  
  832.         for (x = 0; x < dst.cols; x += bcols0) {  
  833.             int brows = std::min(brows0, range.end - y);  
  834.             int bcols = std::min(bcols0, dst.cols - x);  
  835.             Mat_<_Tp1, chs1> dpart;  
  836.             dst.getROI(dpart, Rect(x, y, bcols, brows));  
  837.             Mat_<short, 2> bufxy;  
  838.             _bufxy.getROI(bufxy, Rect(0, 0, bcols, brows));  
  839.             Mat_<ushort, 1> bufa;  
  840.             _bufa.getROI(bufa, Rect(0, 0, bcols, brows));  
  841.   
  842.             for (y1 = 0; y1 < brows; y1++) {  
  843.                 short* XY = (short*)bufxy.ptr(y1);  
  844.                 ushort* A = (ushort*)bufa.ptr(y1);  
  845.   
  846.                 if (planar_input) {  
  847.                     const float* sX = (const float*)map1.ptr(y + y1) + x;  
  848.                     const float* sY = (const float*)map2.ptr(y + y1) + x;  
  849.   
  850.                     x1 = 0;  
  851.                     for (; x1 < bcols; x1++) {  
  852.                         int sx = fbcRound(sX[x1] * INTER_TAB_SIZE);  
  853.                         int sy = fbcRound(sY[x1] * INTER_TAB_SIZE);  
  854.                         int v = (sy & (INTER_TAB_SIZE - 1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE - 1));  
  855.                         XY[x1 * 2] = saturate_cast<short>(sx >> INTER_BITS);  
  856.                         XY[x1 * 2 + 1] = saturate_cast<short>(sy >> INTER_BITS);  
  857.                         A[x1] = (ushort)v;  
  858.                     }  
  859.                 } else {  
  860.                     const float* sXY = (const float*)map1.ptr(y + y1) + x * 2;  
  861.                     x1 = 0;  
  862.                     for (x1 = 0; x1 < bcols; x1++) {  
  863.                         int sx = fbcRound(sXY[x1 * 2] * INTER_TAB_SIZE);  
  864.                         int sy = fbcRound(sXY[x1 * 2 + 1] * INTER_TAB_SIZE);  
  865.                         int v = (sy & (INTER_TAB_SIZE - 1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE - 1));  
  866.                         XY[x1 * 2] = saturate_cast<short>(sx >> INTER_BITS);  
  867.                         XY[x1 * 2 + 1] = saturate_cast<short>(sy >> INTER_BITS);  
  868.                         A[x1] = (ushort)v;  
  869.                     }  
  870.                 }  
  871.             }  
  872.   
  873.             if (typeid(_Tp1).name() == typeid(uchar).name()) { // uchar  
  874.                 remapLanczos4<FixedPtCast<int, uchar, INTER_REMAP_COEF_BITS>, short, INTER_REMAP_COEF_SCALE, _Tp1, short, ushort, chs1, 2, 1>(src, dpart, bufxy, bufa, ctab, borderMode, borderValue);  
  875.             }  
  876.             else { // float  
  877.                 remapLanczos4<Cast<floatfloat>, float, 1, _Tp1, short, ushort, chs1, 2, 1>(src, dpart, bufxy, bufa, ctab, borderMode, borderValue);  
  878.             }  
  879.         }  
  880.     }  
  881.   
  882.     return 0;  
  883. }  
  884.   
  885. // 命名空间fbc
  886.   
  887. #endif // FBC_CV_REMAP_HPP_  

 

除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自OpenCV代码提取:重新映射(remap)函数的实现

留言与评论(共有 0 条评论)
   
验证码:
[lianlun]1[/lianlun]