首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

OpenCV中resize函数五种插值算法的实现过程

  • 23-09-22 20:03
  • 2128
  • 10634
blog.csdn.net

最新版OpenCV2.4.7中,cv::resize函数有五种插值算法:最近邻、双线性、双三次、基于像素区域关系、兰索斯插值。下面用for循环代替cv::resize函数来说明其详细的插值实现过程,其中部分代码摘自于cv::resize函数中的源代码。

每种插值算法的前部分代码是相同的,如下:

  1. cv::Mat matSrc, matDst1, matDst2;
  2. matSrc = cv::imread("lena.jpg", 2 | 4);
  3. matDst1 = cv::Mat(cv::Size(800, 1000), matSrc.type(), cv::Scalar::all(0));
  4. matDst2 = cv::Mat(matDst1.size(), matSrc.type(), cv::Scalar::all(0));
  5. double scale_x = (double)matSrc.cols / matDst1.cols;
  6. double scale_y = (double)matSrc.rows / matDst1.rows;

1、最近邻:公式,

                  

 

  1. for (int i = 0; i < matDst1.cols; ++i)
  2. {
  3. int sx = cvFloor(i * scale_x);
  4. sx = std::min(sx, matSrc.cols - 1);
  5. for (int j = 0; j < matDst1.rows; ++j)
  6. {
  7. int sy = cvFloor(j * scale_y);
  8. sy = std::min(sy, matSrc.rows - 1);
  9. matDst1.at(j, i) = matSrc.at(sy, sx);
  10. }
  11. }
  12. cv::imwrite("nearest_1.jpg", matDst1);
  13. cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 0);
  14. cv::imwrite("nearest_2.jpg", matDst2);

2、双线性:由相邻的四像素(2*2)计算得出,公式,

 

  1. uchar* dataDst = matDst1.data;
  2. int stepDst = matDst1.step;
  3. uchar* dataSrc = matSrc.data;
  4. int stepSrc = matSrc.step;
  5. int iWidthSrc = matSrc.cols;
  6. int iHiehgtSrc = matSrc.rows;
  7. for (int j = 0; j < matDst1.rows; ++j)
  8. {
  9. float fy = (float)((j + 0.5) * scale_y - 0.5);
  10. int sy = cvFloor(fy);
  11. fy -= sy;
  12. sy = std::min(sy, iHiehgtSrc - 2);
  13. sy = std::max(0, sy);
  14. short cbufy[2];
  15. cbufy[0] = cv::saturate_cast<short>((1.f - fy) * 2048);
  16. cbufy[1] = 2048 - cbufy[0];
  17. for (int i = 0; i < matDst1.cols; ++i)
  18. {
  19. float fx = (float)((i + 0.5) * scale_x - 0.5);
  20. int sx = cvFloor(fx);
  21. fx -= sx;
  22. if (sx < 0) {
  23. fx = 0, sx = 0;
  24. }
  25. if (sx >= iWidthSrc - 1) {
  26. fx = 0, sx = iWidthSrc - 2;
  27. }
  28. short cbufx[2];
  29. cbufx[0] = cv::saturate_cast<short>((1.f - fx) * 2048);
  30. cbufx[1] = 2048 - cbufx[0];
  31. for (int k = 0; k < matSrc.channels(); ++k)
  32. {
  33. *(dataDst+ j*stepDst + 3*i + k) = (*(dataSrc + sy*stepSrc + 3*sx + k) * cbufx[0] * cbufy[0] +
  34. *(dataSrc + (sy+1)*stepSrc + 3*sx + k) * cbufx[0] * cbufy[1] +
  35. *(dataSrc + sy*stepSrc + 3*(sx+1) + k) * cbufx[1] * cbufy[0] +
  36. *(dataSrc + (sy+1)*stepSrc + 3*(sx+1) + k) * cbufx[1] * cbufy[1]) >> 22;
  37. }
  38. }
  39. }
  40. cv::imwrite("linear_1.jpg", matDst1);
  41. cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 1);
  42. cv::imwrite("linear_2.jpg", matDst2);

3、双三次:由相邻的4*4像素计算得出,公式类似于双线性

  1. int iscale_x = cv::saturate_cast<int>(scale_x);
  2. int iscale_y = cv::saturate_cast<int>(scale_y);
  3. for (int j = 0; j < matDst1.rows; ++j)
  4. {
  5. float fy = (float)((j + 0.5) * scale_y - 0.5);
  6. int sy = cvFloor(fy);
  7. fy -= sy;
  8. sy = std::min(sy, matSrc.rows - 3);
  9. sy = std::max(1, sy);
  10. const float A = -0.75f;
  11. float coeffsY[4];
  12. coeffsY[0] = ((A*(fy + 1) - 5*A)*(fy + 1) + 8*A)*(fy + 1) - 4*A;
  13. coeffsY[1] = ((A + 2)*fy - (A + 3))*fy*fy + 1;
  14. coeffsY[2] = ((A + 2)*(1 - fy) - (A + 3))*(1 - fy)*(1 - fy) + 1;
  15. coeffsY[3] = 1.f - coeffsY[0] - coeffsY[1] - coeffsY[2];
  16. short cbufY[4];
  17. cbufY[0] = cv::saturate_cast<short>(coeffsY[0] * 2048);
  18. cbufY[1] = cv::saturate_cast<short>(coeffsY[1] * 2048);
  19. cbufY[2] = cv::saturate_cast<short>(coeffsY[2] * 2048);
  20. cbufY[3] = cv::saturate_cast<short>(coeffsY[3] * 2048);
  21. for (int i = 0; i < matDst1.cols; ++i)
  22. {
  23. float fx = (float)((i + 0.5) * scale_x - 0.5);
  24. int sx = cvFloor(fx);
  25. fx -= sx;
  26. if (sx < 1) {
  27. fx = 0, sx = 1;
  28. }
  29. if (sx >= matSrc.cols - 3) {
  30. fx = 0, sx = matSrc.cols - 3;
  31. }
  32. float coeffsX[4];
  33. coeffsX[0] = ((A*(fx + 1) - 5*A)*(fx + 1) + 8*A)*(fx + 1) - 4*A;
  34. coeffsX[1] = ((A + 2)*fx - (A + 3))*fx*fx + 1;
  35. coeffsX[2] = ((A + 2)*(1 - fx) - (A + 3))*(1 - fx)*(1 - fx) + 1;
  36. coeffsX[3] = 1.f - coeffsX[0] - coeffsX[1] - coeffsX[2];
  37. short cbufX[4];
  38. cbufX[0] = cv::saturate_cast<short>(coeffsX[0] * 2048);
  39. cbufX[1] = cv::saturate_cast<short>(coeffsX[1] * 2048);
  40. cbufX[2] = cv::saturate_cast<short>(coeffsX[2] * 2048);
  41. cbufX[3] = cv::saturate_cast<short>(coeffsX[3] * 2048);
  42. for (int k = 0; k < matSrc.channels(); ++k)
  43. {
  44. matDst1.at(j, i)[k] = abs((matSrc.at(sy-1, sx-1)[k] * cbufX[0] * cbufY[0] + matSrc.at(sy, sx-1)[k] * cbufX[0] * cbufY[1] +
  45. matSrc.at(sy+1, sx-1)[k] * cbufX[0] * cbufY[2] + matSrc.at(sy+2, sx-1)[k] * cbufX[0] * cbufY[3] +
  46. matSrc.at(sy-1, sx)[k] * cbufX[1] * cbufY[0] + matSrc.at(sy, sx)[k] * cbufX[1] * cbufY[1] +
  47. matSrc.at(sy+1, sx)[k] * cbufX[1] * cbufY[2] + matSrc.at(sy+2, sx)[k] * cbufX[1] * cbufY[3] +
  48. matSrc.at(sy-1, sx+1)[k] * cbufX[2] * cbufY[0] + matSrc.at(sy, sx+1)[k] * cbufX[2] * cbufY[1] +
  49. matSrc.at(sy+1, sx+1)[k] * cbufX[2] * cbufY[2] + matSrc.at(sy+2, sx+1)[k] * cbufX[2] * cbufY[3] +
  50. matSrc.at(sy-1, sx+2)[k] * cbufX[3] * cbufY[0] + matSrc.at(sy, sx+2)[k] * cbufX[3] * cbufY[1] +
  51. matSrc.at(sy+1, sx+2)[k] * cbufX[3] * cbufY[2] + matSrc.at(sy+2, sx+2)[k] * cbufX[3] * cbufY[3] ) >> 22);
  52. }
  53. }
  54. }
  55. cv::imwrite("cubic_1.jpg", matDst1);
  56. cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 2);
  57. cv::imwrite("cubic_2.jpg", matDst2);

4、基于像素区域关系:共分三种情况,图像放大时类似于双线性插值,图像缩小(x轴、y轴同时缩小)又分两种情况,此情况下可以避免波纹出现。

  1. #ifdef _MSC_VER
  2. cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 3);
  3. cv::imwrite("E:/GitCode/OpenCV_Test/test_images/area_2.jpg", matDst2);
  4. #else
  5. cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 3);
  6. cv::imwrite("area_2.jpg", matDst2);
  7. #endif
  8. fprintf(stdout, "==== start area ==== ");
  9. double inv_scale_x = 1. / scale_x;
  10. double inv_scale_y = 1. / scale_y;
  11. int iscale_x = cv::saturate_cast<int>(scale_x);
  12. int iscale_y = cv::saturate_cast<int>(scale_y);
  13. bool is_area_fast = std::abs(scale_x - iscale_x) < DBL_EPSILON && std::abs(scale_y - iscale_y) < DBL_EPSILON;
  14. if (scale_x >= 1 && scale_y >= 1) { // zoom out
  15. if (is_area_fast) { // integer multiples
  16. for (int j = 0; j < matDst1.rows; ++j) {
  17. int sy = std::min(cvFloor(j * scale_y), matSrc.rows - 1);
  18. for (int i = 0; i < matDst1.cols; ++i) {
  19. int sx = std::min(cvFloor(i * scale_x), matSrc.cols -1);
  20. matDst1.at(j, i) = matSrc.at(sy, sx);
  21. }
  22. }
  23. #ifdef _MSC_VER
  24. cv::imwrite("E:/GitCode/OpenCV_Test/test_images/area_1.jpg", matDst1);
  25. #else
  26. cv::imwrite("area_1.jpg", matDst1);
  27. #endif
  28. return 0;
  29. }
  30. for (int j = 0; j < matDst1.rows; ++j) {
  31. double fsy1 = j * scale_y;
  32. double fsy2 = fsy1 + scale_y;
  33. double cellHeight = cv::min(scale_y, matSrc.rows - fsy1);
  34. int sy1 = cvCeil(fsy1), sy2 = cvFloor(fsy2);
  35. sy2 = std::min(sy2, matSrc.rows - 2);
  36. sy1 = std::min(sy1, sy2);
  37. float cbufy[2];
  38. cbufy[0] = (float)((sy1 - fsy1) / cellHeight);
  39. cbufy[1] = (float)(std::min(std::min(fsy2 - sy2, 1.), cellHeight) / cellHeight);
  40. for (int i = 0; i < matDst1.cols; ++i) {
  41. double fsx1 = i * scale_x;
  42. double fsx2 = fsx1 + scale_x;
  43. double cellWidth = std::min(scale_x, matSrc.cols - fsx1);
  44. int sx1 = cvCeil(fsx1), sx2 = cvFloor(fsx2);
  45. sx2 = std::min(sx2, matSrc.cols - 2);
  46. sx1 = std::min(sx1, sx2);
  47. float cbufx[2];
  48. cbufx[0] = (float)((sx1 - fsx1) / cellWidth);
  49. cbufx[1] = (float)(std::min(std::min(fsx2 - sx2, 1.), cellWidth) / cellWidth);
  50. for (int k = 0; k < matSrc.channels(); ++k) {
  51. matDst1.at(j, i)[k] = (uchar)(matSrc.at(sy1, sx1)[k] * cbufx[0] * cbufy[0] +
  52. matSrc.at(sy1 + 1, sx1)[k] * cbufx[0] * cbufy[1] +
  53. matSrc.at(sy1, sx1 + 1)[k] * cbufx[1] * cbufy[0] +
  54. matSrc.at(sy1 + 1, sx1 + 1)[k] * cbufx[1] * cbufy[1]);
  55. }
  56. }
  57. }
  58. #ifdef _MSC_VER
  59. cv::imwrite("E:/GitCode/OpenCV_Test/test_images/area_1.jpg", matDst1);
  60. #else
  61. cv::imwrite("area_1.jpg", matDst1);
  62. #endif
  63. return 0;
  64. }
  65. //zoom in,it is emulated using some variant of bilinear interpolation
  66. for (int j = 0; j < matDst1.rows; ++j) {
  67. int sy = cvFloor(j * scale_y);
  68. float fy = (float)((j + 1) - (sy + 1) * inv_scale_y);
  69. fy = fy <= 0 ? 0.f : fy - cvFloor(fy);
  70. sy = std::min(sy, matSrc.rows - 2);
  71. short cbufy[2];
  72. cbufy[0] = cv::saturate_cast<short>((1.f - fy) * 2048);
  73. cbufy[1] = 2048 - cbufy[0];
  74. for (int i = 0; i < matDst1.cols; ++i) {
  75. int sx = cvFloor(i * scale_x);
  76. float fx = (float)((i + 1) - (sx + 1) * inv_scale_x);
  77. fx = fx < 0 ? 0.f : fx - cvFloor(fx);
  78. if (sx < 0) {
  79. fx = 0, sx = 0;
  80. }
  81. if (sx >= matSrc.cols - 1) {
  82. fx = 0, sx = matSrc.cols - 2;
  83. }
  84. short cbufx[2];
  85. cbufx[0] = cv::saturate_cast<short>((1.f - fx) * 2048);
  86. cbufx[1] = 2048 - cbufx[0];
  87. for (int k = 0; k < matSrc.channels(); ++k) {
  88. matDst1.at(j, i)[k] = (matSrc.at(sy, sx)[k] * cbufx[0] * cbufy[0] +
  89. matSrc.at(sy + 1, sx)[k] * cbufx[0] * cbufy[1] +
  90. matSrc.at(sy, sx + 1)[k] * cbufx[1] * cbufy[0] +
  91. matSrc.at(sy + 1, sx + 1)[k] * cbufx[1] * cbufy[1]) >> 22;
  92. }
  93. }
  94. }
  95. fprintf(stdout, "==== end area ==== ");
  96. #ifdef _MSC_VER
  97. cv::imwrite("E:/GitCode/OpenCV_Test/test_images/area_1.jpg", matDst1);
  98. #else
  99. cv::imwrite("area_1.jpg", matDst1);
  100. #endif

注:以上基于area进行图像缩小的代码有问题,具体实现代码可以参考http://iyenn.com/index/link?url=https://github.com/fengbingchun/OpenCV_Test/blob/master/src/fbc_cv/include/resize.hpp,用法如下:

  1. fbc::Mat3BGR src(matSrc.rows, matSrc.cols, matSrc.data);
  2. fbc::Mat3BGR dst(matDst1.rows, matDst1.cols, matDst1.data);
  3. fbc::resize(src, dst, 3);

5、兰索斯插值:由相邻的8*8像素计算得出,公式类似于双线性

  1. int iscale_x = cv::saturate_cast<int>(scale_x);
  2. int iscale_y = cv::saturate_cast<int>(scale_y);
  3. for (int j = 0; j < matDst1.rows; ++j)
  4. {
  5. float fy = (float)((j + 0.5) * scale_y - 0.5);
  6. int sy = cvFloor(fy);
  7. fy -= sy;
  8. sy = std::min(sy, matSrc.rows - 5);
  9. sy = std::max(3, sy);
  10. const double s45 = 0.70710678118654752440084436210485;
  11. const double cs[][2] = {{1, 0}, {-s45, -s45}, {0, 1}, {s45, -s45}, {-1, 0}, {s45, s45}, {0, -1}, {-s45, s45}};
  12. float coeffsY[8];
  13. if (fy < FLT_EPSILON) {
  14. for (int t = 0; t < 8; t++)
  15. coeffsY[t] = 0;
  16. coeffsY[3] = 1;
  17. } else {
  18. float sum = 0;
  19. double y0 = -(fy + 3) * CV_PI * 0.25, s0 = sin(y0), c0 = cos(y0);
  20. for (int t = 0; t < 8; ++t)
  21. {
  22. double dy = -(fy + 3 -t) * CV_PI * 0.25;
  23. coeffsY[t] = (float)((cs[t][0] * s0 + cs[t][1] * c0) / (dy * dy));
  24. sum += coeffsY[t];
  25. }
  26. sum = 1.f / sum;
  27. for (int t = 0; t < 8; ++t)
  28. coeffsY[t] *= sum;
  29. }
  30. short cbufY[8];
  31. cbufY[0] = cv::saturate_cast<short>(coeffsY[0] * 2048);
  32. cbufY[1] = cv::saturate_cast<short>(coeffsY[1] * 2048);
  33. cbufY[2] = cv::saturate_cast<short>(coeffsY[2] * 2048);
  34. cbufY[3] = cv::saturate_cast<short>(coeffsY[3] * 2048);
  35. cbufY[4] = cv::saturate_cast<short>(coeffsY[4] * 2048);
  36. cbufY[5] = cv::saturate_cast<short>(coeffsY[5] * 2048);
  37. cbufY[6] = cv::saturate_cast<short>(coeffsY[6] * 2048);
  38. cbufY[7] = cv::saturate_cast<short>(coeffsY[7] * 2048);
  39. for (int i = 0; i < matDst1.cols; ++i)
  40. {
  41. float fx = (float)((i + 0.5) * scale_x - 0.5);
  42. int sx = cvFloor(fx);
  43. fx -= sx;
  44. if (sx < 3) {
  45. fx = 0, sx = 3;
  46. }
  47. if (sx >= matSrc.cols - 5) {
  48. fx = 0, sx = matSrc.cols - 5;
  49. }
  50. float coeffsX[8];
  51. if (fx < FLT_EPSILON) {
  52. for ( int t = 0; t < 8; t++ )
  53. coeffsX[t] = 0;
  54. coeffsX[3] = 1;
  55. } else {
  56. float sum = 0;
  57. double x0 = -(fx + 3) * CV_PI * 0.25, s0 = sin(x0), c0 = cos(x0);
  58. for (int t = 0; t < 8; ++t)
  59. {
  60. double dx = -(fx + 3 -t) * CV_PI * 0.25;
  61. coeffsX[t] = (float)((cs[t][0] * s0 + cs[t][1] * c0) / (dx * dx));
  62. sum += coeffsX[t];
  63. }
  64. sum = 1.f / sum;
  65. for (int t = 0; t < 8; ++t)
  66. coeffsX[t] *= sum;
  67. }
  68. short cbufX[8];
  69. cbufX[0] = cv::saturate_cast<short>(coeffsX[0] * 2048);
  70. cbufX[1] = cv::saturate_cast<short>(coeffsX[1] * 2048);
  71. cbufX[2] = cv::saturate_cast<short>(coeffsX[2] * 2048);
  72. cbufX[3] = cv::saturate_cast<short>(coeffsX[3] * 2048);
  73. cbufX[4] = cv::saturate_cast<short>(coeffsX[4] * 2048);
  74. cbufX[5] = cv::saturate_cast<short>(coeffsX[5] * 2048);
  75. cbufX[6] = cv::saturate_cast<short>(coeffsX[6] * 2048);
  76. cbufX[7] = cv::saturate_cast<short>(coeffsX[7] * 2048);
  77. for (int k = 0; k < matSrc.channels(); ++k)
  78. {
  79. matDst1.at(j, i)[k] = abs((matSrc.at(sy-3, sx-3)[k] * cbufX[0] * cbufY[0] + matSrc.at(sy-2, sx-3)[k] * cbufX[0] * cbufY[1] +
  80. matSrc.at(sy-1, sx-3)[k] * cbufX[0] * cbufY[2] + matSrc.at(sy, sx-3)[k] * cbufX[0] * cbufY[3] +
  81. matSrc.at(sy+1, sx-3)[k] * cbufX[0] * cbufY[4] + matSrc.at(sy+2, sx-3)[k] * cbufX[0] * cbufY[5] +
  82. matSrc.at(sy+3, sx-3)[k] * cbufX[0] * cbufY[6] + matSrc.at(sy+4, sx-3)[k] * cbufX[0] * cbufY[7] +
  83. matSrc.at(sy-3, sx-2)[k] * cbufX[1] * cbufY[0] + matSrc.at(sy-2, sx-2)[k] * cbufX[1] * cbufY[1] +
  84. matSrc.at(sy-1, sx-2)[k] * cbufX[1] * cbufY[2] + matSrc.at(sy, sx-2)[k] * cbufX[1] * cbufY[3] +
  85. matSrc.at(sy+1, sx-2)[k] * cbufX[1] * cbufY[4] + matSrc.at(sy+2, sx-2)[k] * cbufX[1] * cbufY[5] +
  86. matSrc.at(sy+3, sx-2)[k] * cbufX[1] * cbufY[6] + matSrc.at(sy+4, sx-2)[k] * cbufX[1] * cbufY[7] +
  87. matSrc.at(sy-3, sx-1)[k] * cbufX[2] * cbufY[0] + matSrc.at(sy-2, sx-1)[k] * cbufX[2] * cbufY[1] +
  88. matSrc.at(sy-1, sx-1)[k] * cbufX[2] * cbufY[2] + matSrc.at(sy, sx-1)[k] * cbufX[2] * cbufY[3] +
  89. matSrc.at(sy+1, sx-1)[k] * cbufX[2] * cbufY[4] + matSrc.at(sy+2, sx-1)[k] * cbufX[2] * cbufY[5] +
  90. matSrc.at(sy+3, sx-1)[k] * cbufX[2] * cbufY[6] + matSrc.at(sy+4, sx-1)[k] * cbufX[2] * cbufY[7] +
  91. matSrc.at(sy-3, sx)[k] * cbufX[3] * cbufY[0] + matSrc.at(sy-2, sx)[k] * cbufX[3] * cbufY[1] +
  92. matSrc.at(sy-1, sx)[k] * cbufX[3] * cbufY[2] + matSrc.at(sy, sx)[k] * cbufX[3] * cbufY[3] +
  93. matSrc.at(sy+1, sx)[k] * cbufX[3] * cbufY[4] + matSrc.at(sy+2, sx)[k] * cbufX[3] * cbufY[5] +
  94. matSrc.at(sy+3, sx)[k] * cbufX[3] * cbufY[6] + matSrc.at(sy+4, sx)[k] * cbufX[3] * cbufY[7] +
  95. matSrc.at(sy-3, sx+1)[k] * cbufX[4] * cbufY[0] + matSrc.at(sy-2, sx+1)[k] * cbufX[4] * cbufY[1] +
  96. matSrc.at(sy-1, sx+1)[k] * cbufX[4] * cbufY[2] + matSrc.at(sy, sx+1)[k] * cbufX[4] * cbufY[3] +
  97. matSrc.at(sy+1, sx+1)[k] * cbufX[4] * cbufY[4] + matSrc.at(sy+2, sx+1)[k] * cbufX[4] * cbufY[5] +
  98. matSrc.at(sy+3, sx+1)[k] * cbufX[4] * cbufY[6] + matSrc.at(sy+4, sx+1)[k] * cbufX[4] * cbufY[7] +
  99. matSrc.at(sy-3, sx+2)[k] * cbufX[5] * cbufY[0] + matSrc.at(sy-2, sx+2)[k] * cbufX[5] * cbufY[1] +
  100. matSrc.at(sy-1, sx+2)[k] * cbufX[5] * cbufY[2] + matSrc.at(sy, sx+2)[k] * cbufX[5] * cbufY[3] +
  101. matSrc.at(sy+1, sx+2)[k] * cbufX[5] * cbufY[4] + matSrc.at(sy+2, sx+2)[k] * cbufX[5] * cbufY[5] +
  102. matSrc.at(sy+3, sx+2)[k] * cbufX[5] * cbufY[6] + matSrc.at(sy+4, sx+2)[k] * cbufX[5] * cbufY[7] +
  103. matSrc.at(sy-3, sx+3)[k] * cbufX[6] * cbufY[0] + matSrc.at(sy-2, sx+3)[k] * cbufX[6] * cbufY[1] +
  104. matSrc.at(sy-1, sx+3)[k] * cbufX[6] * cbufY[2] + matSrc.at(sy, sx+3)[k] * cbufX[6] * cbufY[3] +
  105. matSrc.at(sy+1, sx+3)[k] * cbufX[6] * cbufY[4] + matSrc.at(sy+2, sx+3)[k] * cbufX[6] * cbufY[5] +
  106. matSrc.at(sy+3, sx+3)[k] * cbufX[6] * cbufY[6] + matSrc.at(sy+4, sx+3)[k] * cbufX[6] * cbufY[7] +
  107. matSrc.at(sy-3, sx+4)[k] * cbufX[7] * cbufY[0] + matSrc.at(sy-2, sx+4)[k] * cbufX[7] * cbufY[1] +
  108. matSrc.at(sy-1, sx+4)[k] * cbufX[7] * cbufY[2] + matSrc.at(sy, sx+4)[k] * cbufX[7] * cbufY[3] +
  109. matSrc.at(sy+1, sx+4)[k] * cbufX[7] * cbufY[4] + matSrc.at(sy+2, sx+4)[k] * cbufX[7] * cbufY[5] +
  110. matSrc.at(sy+3, sx+4)[k] * cbufX[7] * cbufY[6] + matSrc.at(sy+4, sx+4)[k] * cbufX[7] * cbufY[7] ) >> 22);// 4194304
  111. }
  112. }
  113. }
  114. cv::imwrite("Lanczos_1.jpg", matDst1);
  115. cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 4);
  116. cv::imwrite("Lanczos_2.jpg", matDst2);

以上代码的实现结果与cv::resize函数相同,但是执行效率非常低,只是为了详细说明插值过程。OpenCV中默认采用C++ Concurrency进行优化加速,你也可以采用TBB、OpenMP等进行优化加速。

GitHub:http://iyenn.com/index/link?url=https://github.com/fengbingchun/OpenCV_Test/blob/master/demo/OpenCV_Test/test_opencv_funset.cpp

文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览51048 人正在系统学习中
注:本文转载自blog.csdn.net的fengbingchun的文章"https://blog.csdn.net/fengbingchun/article/details/17335477"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top