#include <opencv2/opencv.hpp>
#include<cmath>
#define PI 3.14159265
using namespace std;
using namespace cv;
// TODO: 在此添加命令处理程序代码
String imagename = "D:\\image\\1.jpg";//自己的图片路径
Mat img1 = imread(imagename, 1);
double jiaodu = -PI / 6;//旋转角度是以π为准的
resize(img1, img1, Size(600, 300));//重新设置图片大小,不设置也可以
imshow("原图", img1);
int cPointB, cPointG, cPointR, x1, y1, centerx, centery, midx, midy;
Mat img2(img1.rows*2, img1.cols*2, CV_8UC3, cv::Scalar(3));//重新定义一个大一点的图片来放置
//变换后的图片
/*cout << img2.rows << " " << img2.cols;
cout << img1.rows << " " << img1.cols << ",";*/
centery = int(img1.rows / 2), centerx = int(img1.cols / 2);//找到旋转中心
midx = cos(jiaodu)*centerx - sin(jiaodu)*centery - centerx;//找到旋转中心 的偏移量
midy = cos(jiaodu)*centery + sin(jiaodu)*centerx - centery;
for (int i = 0; i < img2.rows; i++)
{
for (int j = 0; j < img2.cols; j++)
{//从最后目标图片开始,反向映射回去,因为旋转的时候会造成坐标溢出,则将坐标向下平移,
//达到旋转之后还能够有原图的
x1 = int(cos(jiaodu)*(j- img1.cols/2) - sin(jiaodu)*(i - img1.rows / 2) - midx );
y1 = int(cos(jiaodu)*(i- img1.rows / 2) + sin(jiaodu)*(j - img1.cols / 2) - midy);
//判断如果反映射回去超过原图区域,则没有像素值,直接省去
if (x1 < 0 || x1 >= img1.cols || y1 < 0 || y1 >= img1.rows)
{
img2.at<Vec3b>(i, j)[0] = 0;
img2.at<Vec3b>(i, j)[0] = 0;
img2.at<Vec3b>(i, j)[0] = 0;
continue;
}
//cout << x1 << " " << y1 << ",";
img2.at<Vec3b>(i, j)[0] = img1.at<Vec3b>(y1, x1)[0];
img2.at<Vec3b>(i, j)[1] = img1.at<Vec3b>(y1, x1)[1];
img2.at<Vec3b>(i, j)[2] = img1.at<Vec3b>(y1, x1)[2];
}
}
imshow("30度旋转", img2);