aihot  2017-05-26 21:45:51  OpenCV |   查看评论   

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

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

 

除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自OpenCV中resize函数五种插值算法的实现过程

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