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