当前位置:   article > 正文

OpenCV函数cvRemap源代码_opencv remap源码

opencv remap源码

cvRemap源代码

  1. void cv::remap( InputArray _src, OutputArray _dst,
  2. InputArray _map1, InputArray _map2,
  3. int interpolation, int borderType, const Scalar& borderValue )
  4. {
  5. static RemapNNFunc nn_tab[] =
  6. {
  7. remapNearest<uchar>, remapNearest<schar>, remapNearest<ushort>, remapNearest<short>,
  8. remapNearest<int>, remapNearest<float>, remapNearest<double>, 0
  9. };
  10. static RemapFunc linear_tab[] =
  11. {
  12. remapBilinear<FixedPtCast<int, uchar, INTER_REMAP_COEF_BITS>, RemapVec_8u, short>, 0,
  13. remapBilinear<Cast<float, ushort>, RemapNoVec, float>,
  14. remapBilinear<Cast<float, short>, RemapNoVec, float>, 0,
  15. remapBilinear<Cast<float, float>, RemapNoVec, float>,
  16. remapBilinear<Cast<double, double>, RemapNoVec, float>, 0
  17. };
  18. static RemapFunc cubic_tab[] =
  19. {
  20. remapBicubic<FixedPtCast<int, uchar, INTER_REMAP_COEF_BITS>, short, INTER_REMAP_COEF_SCALE>, 0,
  21. remapBicubic<Cast<float, ushort>, float, 1>,
  22. remapBicubic<Cast<float, short>, float, 1>, 0,
  23. remapBicubic<Cast<float, float>, float, 1>,
  24. remapBicubic<Cast<double, double>, float, 1>, 0
  25. };
  26. static RemapFunc lanczos4_tab[] =
  27. {
  28. remapLanczos4<FixedPtCast<int, uchar, INTER_REMAP_COEF_BITS>, short, INTER_REMAP_COEF_SCALE>, 0,
  29. remapLanczos4<Cast<float, ushort>, float, 1>,
  30. remapLanczos4<Cast<float, short>, float, 1>, 0,
  31. remapLanczos4<Cast<float, float>, float, 1>,
  32. remapLanczos4<Cast<double, double>, float, 1>, 0
  33. };
  34. Mat src = _src.getMat(), map1 = _map1.getMat(), map2 = _map2.getMat();
  35. CV_Assert( (!map2.data || map2.size() == map1.size()));
  36. _dst.create( map1.size(), src.type() );
  37. Mat dst = _dst.getMat();
  38. if( dst.data == src.data )
  39. src = src.clone();
  40. int depth = src.depth(), map_depth = map1.depth();
  41. RemapNNFunc nnfunc = 0;
  42. RemapFunc ifunc = 0;
  43. const void* ctab = 0;
  44. bool fixpt = depth == CV_8U;
  45. bool planar_input = false;
  46. if( interpolation == INTER_NEAREST )
  47. {
  48. nnfunc = nn_tab[depth];
  49. CV_Assert( nnfunc != 0 );
  50. if( map1.type() == CV_16SC2 && !map2.data ) // the data is already in the right format
  51. {
  52. nnfunc( src, dst, map1, borderType, borderValue );
  53. return;
  54. }
  55. }
  56. else
  57. {
  58. if( interpolation == INTER_AREA )
  59. interpolation = INTER_LINEAR;
  60. if( interpolation == INTER_LINEAR )
  61. ifunc = linear_tab[depth];
  62. else if( interpolation == INTER_CUBIC )
  63. ifunc = cubic_tab[depth];
  64. else if( interpolation == INTER_LANCZOS4 )
  65. ifunc = lanczos4_tab[depth];
  66. else
  67. CV_Error( CV_StsBadArg, "Unknown interpolation method" );
  68. CV_Assert( ifunc != 0 );
  69. ctab = initInterTab2D( interpolation, fixpt );
  70. }
  71. const Mat *m1 = &map1, *m2 = &map2;
  72. if( (map1.type() == CV_16SC2 && (map2.type() == CV_16UC1 || map2.type() == CV_16SC1)) ||
  73. (map2.type() == CV_16SC2 && (map1.type() == CV_16UC1 || map1.type() == CV_16SC1)) )
  74. {
  75. if( map1.type() != CV_16SC2 )
  76. std::swap(m1, m2);
  77. if( ifunc )
  78. {
  79. ifunc( src, dst, *m1, *m2, ctab, borderType, borderValue );
  80. return;
  81. }
  82. }
  83. else
  84. {
  85. CV_Assert( (map1.type() == CV_32FC2 && !map2.data) ||
  86. (map1.type() == CV_32FC1 && map2.type() == CV_32FC1) );
  87. planar_input = map1.channels() == 1;
  88. }
  89. int x, y, x1, y1;
  90. const int buf_size = 1 << 14;
  91. int brows0 = std::min(128, dst.rows);
  92. int bcols0 = std::min(buf_size/brows0, dst.cols);
  93. brows0 = std::min(buf_size/bcols0, dst.rows);
  94. #if CV_SSE2
  95. bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
  96. #endif
  97. Mat _bufxy(brows0, bcols0, CV_16SC2), _bufa;
  98. if( !nnfunc )
  99. _bufa.create(brows0, bcols0, CV_16UC1);
  100. for( y = 0; y < dst.rows; y += brows0 )
  101. {
  102. for( x = 0; x < dst.cols; x += bcols0 )
  103. {
  104. int brows = std::min(brows0, dst.rows - y);
  105. int bcols = std::min(bcols0, dst.cols - x);
  106. Mat dpart(dst, Rect(x, y, bcols, brows));
  107. Mat bufxy(_bufxy, Rect(0, 0, bcols, brows));
  108. if( nnfunc )
  109. {
  110. if( map_depth != CV_32F )
  111. {
  112. for( y1 = 0; y1 < brows; y1++ )
  113. {
  114. short* XY = (short*)(bufxy.data + bufxy.step*y1);
  115. const short* sXY = (const short*)(m1->data + m1->step*(y+y1)) + x*2;
  116. const ushort* sA = (const ushort*)(m2->data + m2->step*(y+y1)) + x;
  117. for( x1 = 0; x1 < bcols; x1++ )
  118. {
  119. int a = sA[x1] & (INTER_TAB_SIZE2-1);
  120. XY[x1*2] = sXY[x1*2] + NNDeltaTab_i[a][0];
  121. XY[x1*2+1] = sXY[x1*2+1] + NNDeltaTab_i[a][1];
  122. }
  123. }
  124. }
  125. else if( !planar_input )
  126. map1(Rect(0,0,bcols,brows)).convertTo(bufxy, bufxy.depth());
  127. else
  128. {
  129. for( y1 = 0; y1 < brows; y1++ )
  130. {
  131. short* XY = (short*)(bufxy.data + bufxy.step*y1);
  132. const float* sX = (const float*)(map1.data + map1.step*(y+y1)) + x;
  133. const float* sY = (const float*)(map2.data + map2.step*(y+y1)) + x;
  134. x1 = 0;
  135. #if CV_SSE2
  136. if( useSIMD )
  137. {
  138. for( ; x1 <= bcols - 8; x1 += 8 )
  139. {
  140. __m128 fx0 = _mm_loadu_ps(sX + x1);
  141. __m128 fx1 = _mm_loadu_ps(sX + x1 + 4);
  142. __m128 fy0 = _mm_loadu_ps(sY + x1);
  143. __m128 fy1 = _mm_loadu_ps(sY + x1 + 4);
  144. __m128i ix0 = _mm_cvtps_epi32(fx0);
  145. __m128i ix1 = _mm_cvtps_epi32(fx1);
  146. __m128i iy0 = _mm_cvtps_epi32(fy0);
  147. __m128i iy1 = _mm_cvtps_epi32(fy1);
  148. ix0 = _mm_packs_epi32(ix0, ix1);
  149. iy0 = _mm_packs_epi32(iy0, iy1);
  150. ix1 = _mm_unpacklo_epi16(ix0, iy0);
  151. iy1 = _mm_unpackhi_epi16(ix0, iy0);
  152. _mm_storeu_si128((__m128i*)(XY + x1*2), ix1);
  153. _mm_storeu_si128((__m128i*)(XY + x1*2 + 8), iy1);
  154. }
  155. }
  156. #endif
  157. for( ; x1 < bcols; x1++ )
  158. {
  159. XY[x1*2] = saturate_cast<short>(sX[x1]);
  160. XY[x1*2+1] = saturate_cast<short>(sY[x1]);
  161. }
  162. }
  163. }
  164. nnfunc( src, dpart, bufxy, borderType, borderValue );
  165. continue;
  166. }
  167. Mat bufa(_bufa, Rect(0,0,bcols, brows));
  168. for( y1 = 0; y1 < brows; y1++ )
  169. {
  170. short* XY = (short*)(bufxy.data + bufxy.step*y1);
  171. ushort* A = (ushort*)(bufa.data + bufa.step*y1);
  172. if( planar_input )
  173. {
  174. const float* sX = (const float*)(map1.data + map1.step*(y+y1)) + x;
  175. const float* sY = (const float*)(map2.data + map2.step*(y+y1)) + x;
  176. x1 = 0;
  177. #if CV_SSE2
  178. if( useSIMD )
  179. {
  180. __m128 scale = _mm_set1_ps((float)INTER_TAB_SIZE);
  181. __m128i mask = _mm_set1_epi32(INTER_TAB_SIZE-1);
  182. for( ; x1 <= bcols - 8; x1 += 8 )
  183. {
  184. __m128 fx0 = _mm_loadu_ps(sX + x1);
  185. __m128 fx1 = _mm_loadu_ps(sX + x1 + 4);
  186. __m128 fy0 = _mm_loadu_ps(sY + x1);
  187. __m128 fy1 = _mm_loadu_ps(sY + x1 + 4);
  188. __m128i ix0 = _mm_cvtps_epi32(_mm_mul_ps(fx0, scale));
  189. __m128i ix1 = _mm_cvtps_epi32(_mm_mul_ps(fx1, scale));
  190. __m128i iy0 = _mm_cvtps_epi32(_mm_mul_ps(fy0, scale));
  191. __m128i iy1 = _mm_cvtps_epi32(_mm_mul_ps(fy1, scale));
  192. __m128i mx0 = _mm_and_si128(ix0, mask);
  193. __m128i mx1 = _mm_and_si128(ix1, mask);
  194. __m128i my0 = _mm_and_si128(iy0, mask);
  195. __m128i my1 = _mm_and_si128(iy1, mask);
  196. mx0 = _mm_packs_epi32(mx0, mx1);
  197. my0 = _mm_packs_epi32(my0, my1);
  198. my0 = _mm_slli_epi16(my0, INTER_BITS);
  199. mx0 = _mm_or_si128(mx0, my0);
  200. _mm_storeu_si128((__m128i*)(A + x1), mx0);
  201. ix0 = _mm_srai_epi32(ix0, INTER_BITS);
  202. ix1 = _mm_srai_epi32(ix1, INTER_BITS);
  203. iy0 = _mm_srai_epi32(iy0, INTER_BITS);
  204. iy1 = _mm_srai_epi32(iy1, INTER_BITS);
  205. ix0 = _mm_packs_epi32(ix0, ix1);
  206. iy0 = _mm_packs_epi32(iy0, iy1);
  207. ix1 = _mm_unpacklo_epi16(ix0, iy0);
  208. iy1 = _mm_unpackhi_epi16(ix0, iy0);
  209. _mm_storeu_si128((__m128i*)(XY + x1*2), ix1);
  210. _mm_storeu_si128((__m128i*)(XY + x1*2 + 8), iy1);
  211. }
  212. }
  213. #endif
  214. for( ; x1 < bcols; x1++ )
  215. {
  216. int sx = cvRound(sX[x1]*INTER_TAB_SIZE);
  217. int sy = cvRound(sY[x1]*INTER_TAB_SIZE);
  218. int v = (sy & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE-1));
  219. XY[x1*2] = (short)(sx >> INTER_BITS);
  220. XY[x1*2+1] = (short)(sy >> INTER_BITS);
  221. A[x1] = (ushort)v;
  222. }
  223. }
  224. else
  225. {
  226. const float* sXY = (const float*)(map1.data + map1.step*(y+y1)) + x*2;
  227. for( x1 = 0; x1 < bcols; x1++ )
  228. {
  229. int sx = cvRound(sXY[x1*2]*INTER_TAB_SIZE);
  230. int sy = cvRound(sXY[x1*2+1]*INTER_TAB_SIZE);
  231. int v = (sy & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (sx & (INTER_TAB_SIZE-1));
  232. XY[x1*2] = (short)(sx >> INTER_BITS);
  233. XY[x1*2+1] = (short)(sy >> INTER_BITS);
  234. A[x1] = (ushort)v;
  235. }
  236. }
  237. }
  238. ifunc(src, dpart, bufxy, bufa, ctab, borderType, borderValue);
  239. }
  240. }
  241. }


声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号