OPENCV 旋转图像算法-汇总

 
  1 void ImgRotate(cv::Mat imgIn, float theta, cv::Mat& imgOut)
  2 {
  3     int oldWidth = imgIn.cols;
  4     int oldHeight = imgIn.rows;
  5 
  6     // 源图四个角的坐标(以图像中心为坐标系原点)
  7     float fSrcX1, fSrcY1, fSrcX2, fSrcY2, fSrcX3, fSrcY3, fSrcX4, fSrcY4;
  8     fSrcX1 = (float)(-(oldWidth - 1) / 2);
  9     fSrcY1 = (float)((oldHeight - 1) / 2);
 10     fSrcX2 = (float)((oldWidth - 1) / 2);
 11     fSrcY2 = (float)((oldHeight - 1) / 2);
 12     fSrcX3 = (float)(-(oldWidth - 1) / 2);
 13     fSrcY3 = (float)(-(oldHeight - 1) / 2);
 14     fSrcX4 = (float)((oldWidth - 1) / 2);
 15     fSrcY4 = (float)(-(oldHeight - 1) / 2);
 16 
 17     // 旋转后四个角的坐标(以图像中心为坐标系原点)
 18     float fDstX1, fDstY1, fDstX2, fDstY2, fDstX3, fDstY3, fDstX4, fDstY4;
 19     fDstX1 = cos(theta) * fSrcX1 + sin(theta) * fSrcY1;
 20     fDstY1 = -sin(theta) * fSrcX1 + cos(theta) * fSrcY1;
 21     fDstX2 = cos(theta) * fSrcX2 + sin(theta) * fSrcY2;
 22     fDstY2 = -sin(theta) * fSrcX2 + cos(theta) * fSrcY2;
 23     fDstX3 = cos(theta) * fSrcX3 + sin(theta) * fSrcY3;
 24     fDstY3 = -sin(theta) * fSrcX3 + cos(theta) * fSrcY3;
 25     fDstX4 = cos(theta) * fSrcX4 + sin(theta) * fSrcY4;
 26     fDstY4 = -sin(theta) * fSrcX4 + cos(theta) * fSrcY4;
 27 
 28     int newWidth = (max(fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2)) + 0.5);
 29     int newHeight = (max(fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2)) + 0.5);
 30 
 31     imgOut.create(newHeight, newWidth, imgIn.type());
 32 
 33     float dx = -0.5*newWidth*cos(theta) - 0.5*newHeight*sin(theta) + 0.5*oldWidth;
 34     float dy = 0.5*newWidth*sin(theta) - 0.5*newHeight*cos(theta) + 0.5*oldHeight;
 35 
 36     int x, y;
 37     for (int i = 0; i < newHeight; i++)
 38     {
 39         for (int j = 0; j < newWidth; j++)
 40         {
 41             x = float(j)*cos(theta) + float(i)*sin(theta) + dx;
 42             y = float(-j)*sin(theta) + float(i)*cos(theta) + dy;
 43 
 44             if ((x < 0) || (x >= oldWidth) || (y < 0) || (y >= oldHeight))
 45             {
 46                 if (imgIn.channels() == 3)
 47                 {
 48                     imgOut.at<cv::Vec3b>(i, j) = cv::Vec3b(0, 0, 0);
 49                 }
 50                 else if (imgIn.channels() == 1)
 51                 {
 52                     imgOut.at<uchar>(i, j) = 0;
 53                 }
 54             }
 55             else
 56             {
 57                 if (imgIn.channels() == 3)
 58                 {
 59                     imgOut.at<cv::Vec3b>(i, j) = imgIn.at<cv::Vec3b>(y, x);
 60                 }
 61                 else if (imgIn.channels() == 1)
 62                 {
 63                     imgOut.at<uchar>(i, j) = imgIn.at<uchar>(y, x);
 64                 }
 65             }
 66         }
 67     }
 68 }
 69 
 70 
 71 void getAfterRotateRoi(cv::Mat& imgIn, int cols, int rows, Mat& imgOut)
 72 {
 73 
 74     imgOut.create(cols, rows, imgIn.type());
 75     Point center(imgIn.cols / 2, imgIn.rows / 2);
 76 
 77     imgOut = imgIn(Rect(imgIn.cols / 2 - cols / 2, imgIn.rows / 2 - rows / 2, cols,rows));
 78     
 79 }
 80 
 81 Mat ImageRotate2NewSize(Mat& src, const CvPoint &_center, double angle, double scale)
 82 {
 83     double angle2 = angle * CV_PI / 180;
 84     int width = src.cols;
 85     int height = src.rows;
 86 
 87     double alpha = cos(angle2) * scale;
 88     double beta = sin(angle2) * scale;
 89 
 90     int new_width = (int)(width * fabs(alpha) + height * fabs(beta));
 91     int new_height = (int)(width * fabs(beta) + height * fabs(alpha));
 92 
 93     CvPoint2D32f center;
 94     center.x = float(width / 2);
 95     center.y = float(height / 2);
 96     //计算二维旋转的仿射变换矩阵
 97     Mat M = getRotationMatrix2D(center, angle, scale);
 98 
 99     // 给计算得到的旋转矩阵添加平移
100     M.at<double>(0, 2) += (int)((new_width - width) / 2);
101     M.at<double>(1, 2) += (int)((new_height - height) / 2);
102 
103     // rotate
104     Mat dst;
105     warpAffine(src, dst, M, cvSize(new_width, new_height), CV_INTER_LINEAR);
106     return dst;
107 }

 参考:http://www.tuicool.com/articles/RZz2Eb

posted @ 2016-04-28 16:12  DreamFaquir  阅读(469)  评论(0编辑  收藏  举报