上一篇转载的文章(http://blog.csdn.net/carson2005/article/details/36900161)介绍了图像旋转的原理,这里给出代码实现,具体原理请参考上面的链接;
实现代码:
void ImgRotate(cv::Mat imgIn, float theta, cv::Mat& imgOut) { int oldWidth = imgIn.cols; int oldHeight = imgIn.rows; // 源图四个角的坐标(以图像中心为坐标系原点) float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4; fSrcX1 = (float) (- (oldWidth - 1) / 2); fSrcY1 = (float) ( (oldHeight - 1) / 2); fSrcX2 = (float) ( (oldWidth - 1) / 2); fSrcY2 = (float) ( (oldHeight - 1) / 2); fSrcX3 = (float) (- (oldWidth - 1) / 2); fSrcY3 = (float) (- (oldHeight - 1) / 2); fSrcX4 = (float) ( (oldWidth - 1) / 2); fSrcY4 = (float) (- (oldHeight - 1) / 2); // 旋转后四个角的坐标(以图像中心为坐标系原点) float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4; fDstX1 = cos(theta) * fSrcX1 + sin(theta) * fSrcY1; fDstY1 = -sin(theta) * fSrcX1 + cos(theta) * fSrcY1; fDstX2 = cos(theta) * fSrcX2 + sin(theta) * fSrcY2; fDstY2 = -sin(theta) * fSrcX2 + cos(theta) * fSrcY2; fDstX3 = cos(theta) * fSrcX3 + sin(theta) * fSrcY3; fDstY3 = -sin(theta) * fSrcX3 + cos(theta) * fSrcY3; fDstX4 = cos(theta) * fSrcX4 + sin(theta) * fSrcY4; fDstY4 = -sin(theta) * fSrcX4 + cos(theta) * fSrcY4; int newWidth = ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5); int newHeight = ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) ) + 0.5); imgOut.create(newHeight, newWidth, imgIn.type()); float dx = -0.5*newWidth*cos(theta) - 0.5*newHeight*sin(theta) + 0.5*oldWidth; float dy = 0.5*newWidth*sin(theta) - 0.5*newHeight*cos(theta) + 0.5*oldHeight; int x,y; for (int i=0; i<newHeight; i++) { for (int j=0; j<newWidth; j++) { x = float(j)*cos(theta) + float(i)*sin(theta) + dx; y = float(-j)*sin(theta) + float(i)*cos(theta) + dy; if ((x<0) || (x>=oldWidth) || (y<0) || (y>=oldHeight)) { if (imgIn.channels() == 3) { imgOut.at<cv::Vec3b>(i,j) = cv::Vec3b(0,0,0); } else if (imgIn.channels() == 1) { imgOut.at<uchar>(i,j) = 0; } } else { if (imgIn.channels() == 3) { imgOut.at<cv::Vec3b>(i,j) = imgIn.at<cv::Vec3b>(y,x); } else if (imgIn.channels() == 1) { imgOut.at<uchar>(i,j) = imgIn.at<uchar>(y,x); } } } } }
测试代码:
void ImgRotateTest() { cv::Mat srcImg = cv::imread("test.jpg"); if (srcImg.empty()) { printf("srcImg load error \n"); system("pause"); exit(-1); } float angle = 30.0f*3.1415926/180.0f; cv::Mat dstImg; ImgRotate(srcImg, angle, dstImg); cv::imwrite("result.jpg", dstImg); cv::imshow("src", srcImg); cv::imshow("dst", dstImg); cv::waitKey(0); }