aihot  2017-05-26 20:46:01  OpenCV |   查看评论   

 采用双线性插值算法的实现代码为:

  1. cv::Mat matSrc = cv::imread("lena.jpg", 2 | 4);  
  2.   
  3. if (matSrc.empty()) return;  
  4.   
  5. const double degree = 45;  
  6. double angle = degree * CV_PI / 180.;  
  7. double alpha = cos(angle);  
  8. double beta = sin(angle);  
  9. int iWidth = matSrc.cols;  
  10. int iHeight = matSrc.rows;  
  11. int iNewWidth = cvRound(iWidth * fabs(alpha) + iHeight * fabs(beta));  
  12. int iNewHeight = cvRound(iHeight * fabs(alpha) + iWidth * fabs(beta));  
  13.   
  14. double m[6];  
  15. m[0] = alpha;  
  16. m[1] = beta;  
  17. m[2] = (1 - alpha) * iWidth / 2. - beta * iHeight / 2.;  
  18. m[3] = -m[1];  
  19. m[4] = m[0];  
  20. m[5] = beta * iWidth / 2. + (1 - alpha) * iHeight / 2.;  
  21.   
  22. cv::Mat M = cv::Mat(2, 3, CV_64F, m);  
  23. cv::Mat matDst1 = cv::Mat(cv::Size(iNewWidth, iNewHeight), matSrc.type(), cv::Scalar::all(0));  
  24.   
  25. double D = m[0]*m[4] - m[1]*m[3];  
  26. D = D != 0 ? 1./D : 0;  
  27. double A11 = m[4]*D, A22 = m[0]*D;  
  28. m[0] = A11; m[1] *= -D;  
  29. m[3] *= -D; m[4] = A22;  
  30. double b1 = -m[0]*m[2] - m[1]*m[5];  
  31. double b2 = -m[3]*m[2] - m[4]*m[5];  
  32. m[2] = b1; m[5] = b2;  
  33.   
  34. for (int y=0; y<iNewHeight; ++y)  
  35. {  
  36.     for (int x=0; x<iNewWidth; ++x)  
  37.     {  
  38.         //int tmpx = cvFloor(m[0] * x + m[1] * y + m[2]);  
  39.         //int tmpy = cvFloor(m[3] * x + m[4] * y + m[5]);  
  40.         float fx = m[0] * x + m[1] * y + m[2];  
  41.         float fy = m[3] * x + m[4] * y + m[5];  
  42.   
  43.         int sy  = cvFloor(fy);  
  44.         fy -= sy;  
  45.         //sy = std::min(sy, iHeight-2);  
  46.         //sy = std::max(0, sy);  
  47.         if (sy < 0 || sy >= iHeight) continue;  
  48.   
  49.         short cbufy[2];  
  50.         cbufy[0] = cv::saturate_cast<short>((1.f - fy) * 2048);  
  51.         cbufy[1] = 2048 - cbufy[0];  
  52.   
  53.         int sx = cvFloor(fx);  
  54.         fx -= sx;  
  55.         //if (sx < 0) {  
  56.         //  fx = 0, sx = 0;  
  57.         //}  
  58.         //if (sx >= iWidth - 1) {  
  59.         //  fx = 0, sx = iWidth - 2;  
  60.         //}  
  61.         if (sx < 0 || sx >= iWidth) continue;  
  62.   
  63.         short cbufx[2];  
  64.         cbufx[0] = cv::saturate_cast<short>((1.f - fx) * 2048);  
  65.         cbufx[1] = 2048 - cbufx[0];  
  66.   
  67.         for (int k=0; k<matSrc.channels(); ++k)  
  68.         {  
  69.             if (sy == iHeight - 1 || sx == iWidth - 1) {  
  70.                 continue;  
  71.             } else {  
  72.                 matDst1.at<cv::Vec3b>(y, x)[k] = (matSrc.at<cv::Vec3b>(sy, sx)[k] * cbufx[0] * cbufy[0] +  
  73.                     matSrc.at<cv::Vec3b>(sy+1, sx)[k] * cbufx[0] * cbufy[1] +  
  74.                     matSrc.at<cv::Vec3b>(sy, sx+1)[k] * cbufx[1] * cbufy[0] +  
  75.                     matSrc.at<cv::Vec3b>(sy+1, sx+1)[k] * cbufx[1] * cbufy[1]) >> 22;  
  76.             }  
  77.         }  
  78.     }  
  79. }  
  80. cv::imwrite("rotate_bilinear_1.jpg", matDst1);  
  81.   
  82. M = cv::getRotationMatrix2D(cv::Point2f(iWidth / 2., iHeight / 2.), degree, 1);  
  83.   
  84. cv::Mat matDst2;  
  85. cv::warpAffine(matSrc, matDst2, M, cv::Size(iNewWidth, iNewHeight), 1, 0, 0);  
  86. cv::imwrite("rotate_bilinear_2.jpg", matDst2);  
 

除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自OpenCV中图像旋转(warpAffine)算法的实现过程

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