Opencv2.4内并没有直接可使用的函数,因此需代码实现。
实现代码(代码中旋转中心的选取应该是(0,0),但坐标系y轴变成以向上为正了)
#include<iostream>
#include<cmath>
#include"opencv2/imgproc/imgproc.hpp"
#include"opencv2/highgui/highgui.hpp"
#include<opencv2/core/core.hpp>
using namespace std;
using namespace cv;
Mat angleRotate(cv::Mat&src, int angle)
{
//角度转换
float alpha = angle*CV_PI / 180;
//构造旋转矩阵
float rotateMat[3][3] = {
{ cos(alpha), -sin(alpha), 0 },
{ sin(alpha), cos(alpha), 0 },
{ 0, 0, 1 } };
int nSrcRows = src.rows;
int nSrcCols = src.cols;
//计算旋转后图像矩阵的各个顶点位置 、、这里直接以(0,0)作为旋转中心了,但是y轴向上为正
float a1 = nSrcCols*rotateMat[0][0];//(x,0)转换后的x
float b1 = nSrcCols*rotateMat[1][0];//(x,0)转换后的y
float a2 = nSrcCols*rotateMat[0][0] + nSrcRows*rotateMat[0][1];//(x,y)转换后的x
float b2 = nSrcCols*rotateMat[1][0] + nSrcRows*rotateMat[1][1];//(x,y)转换后的y
float a3 = nSrcRows*rotateMat[0][1];//(0,y)转换后的x
float b3 = nSrcRows*rotateMat[1][1];//(0,y)转换后的y
//计算极值点
float kxMin = min(min(min(0.0f, a1), a2), a3);
float kxMax = max(max(max(0.0f, a1), a2), a3);
float kyMin = min(min(min(0.0f, b1), b2), b3);
float kyMax = max(max(max(0.0f, b1), b2), b3);
//计算输出矩阵的尺寸
int nRows = abs(kxMax - kxMin);
int nCols = abs(kyMax - kyMin);
//创建输出矩阵
Mat dst(nRows, nCols, src.type(), Scalar::all(0));
for (int i = 0; i < nRows; ++i){
for (int j = 0; j < nCols; ++j){
//旋转坐标转换
int x = (j + kxMin)*rotateMat[0][0] - (i + kyMin)*rotateMat[0][1];
int y = -(j + kxMin)*rotateMat[1][0] + (i + kyMin)*rotateMat[1][1];
//区域旋转
if ((x >= 0) && (x < nSrcCols) && (y >= 0) && (y < nSrcRows)){
dst.at<Vec3b>(i, j) = src.at<Vec3b>(y, x);
}
}
}
return dst;
}
int main()
{
Mat mat_pic2 = imread("F:\\opencv_re_learn\\2.jpg");
if (mat_pic2.empty()){
cout << "pic is empty" << endl;
system("pause");
return -1;
}
imshow("ori_pic2", mat_pic2);//原图像显示
int angle = 30;
//旋转操作
Mat result = angleRotate(mat_pic2, angle);
imshow("result_liner", result);//显示旋转过后的结果
//按下esc 保存
if (waitKey(-1) == 27){
imwrite("save.jpg", result);
}
return 0;
}