图像的旋转的额基本原理:
图像的每个像素需要经过如下3步完成旋转。
①由输入图像的坐标系转换为数学坐标系。
②通过数学旋转坐标系计算指定像素旋转后的坐标。
③由旋转坐标系转换为输出图像的坐标系。
话不多说放上源代码:
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<cmath>
#include<iostream>
using namespace cv;
using namespace std;
//旋转图像
Mat RotIamge(Mat &srcImage, float Angle) //旋转角度然后返回一张旋转后的图像
{
//以图像的中心为原点求出原图中的四个角的坐标
float SrcX1, SrcY1, SrcX2, SrcY2, SrcX3, SrcY3, SrcX4, SrcY4;
//新图中四个角的坐标
float DstX1, DstY1, DstX2, DstY2, DstX3, DstY3, DstX4, DstY4;
//将角度转换位弧度
float alpha = Angle*CV_PI / 180;
//原图的宽高
int Wold = srcImage.cols;
int Hold = srcImage.rows;
//假设原图的原点在原图的中心主要是为了求出新图的宽高
//原图的四个角的坐标
SrcX1 = (float)((-0.5)*Wold);
SrcY1 = (float)((0.5)*Hold);
SrcX2 = (float)((0.5)*Wold);
SrcY2 = (float)((0.5)*Hold);
SrcX3 = (float)((-0.5)*Wold);
SrcY3 = (float)((-0.5)*Hold);
SrcX4 = (float)((0.5)*Wold);
SrcY4 = (float)((-0.5)*Hold);
//求出cosa 和sina
float cosa = cos(alpha);
float sina = sin(alpha);
//求出新图的四个角的坐标
DstX1 = cosa*SrcX1 + sina*SrcY1;
DstY1 = -sina*SrcX1 + cosa*SrcY1;
DstX2 = cosa*SrcX2 + sina*SrcY2;
DstY2 = -sina*SrcX2 + cosa*SrcY2;
DstX3 = cosa*SrcX3 + sina*SrcY3;
DstY3 = -sina*SrcX3 + cosa*SrcY3;
DstX4 = cosa*SrcX4 + sina*SrcY4;
DstY4 = -sina*SrcX4 + cosa*SrcY4;
//计算新图的宽和高
int Wnew = cvRound(max(abs(DstX4 - DstX1), abs(DstX3 - DstX2)));
int Hnew = cvRound(max(abs(DstY4 - DstY1), abs(DstY3 - DstY2)));
//计算矩阵中的两个常数
float num1 = (float)(-0.5*Wnew*cosa - 0.5*Hnew*sina + 0.5*Wold);
float num2 = (float)(0.5*Wnew*sina - 0.5*Hnew*cosa + 0.5*Hold);
//创建一张新的大小的图
Mat resultImage(Hnew, Wnew, srcImage.type());
for (int i = 0; i < Hnew; i++) //rows
{
for (int j = 0; j < Wnew; j++)//cols
{
//求出新图中的像素在原图的位置
int x = cvRound(i*cosa + j*sina + num1);
int y = cvRound(-sina*i + j*cosa + num2);
if ((x >= 0) && (x < Wold) && (y >= 0) && (y < Hold))//在原图中的范围
{
resultImage.at<Vec3b>(i, j) = srcImage.at<Vec3b>(x, y);
}
}
}
return resultImage;
}
int main()
{
Mat srcImage = imread("lakeWater.jpg");
if (!srcImage.data)
{
printf("image could not load...\n");
return -1;
}
imshow("srcImage", srcImage);
Mat resultImage = RotIamge(srcImage,30);
imshow("resultImage", resultImage);
waitKey(0);
return 0;
}
原图:
旋转之后的效果图: