图像旋转是指图像按照某个位置转动一定的角度的过程,旋转中图像扔保持着原始尺寸。图像旋转后的图像水平对称轴、垂直对称轴及中心坐标原点可能都会发生变换,因此需要对图像旋转中的坐标进行相应的转换。
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#include <cmath>
using namespace std;
cv::Mat angleRotatee(cv::Mat &src, int angle)
{
//角度转换
float alpha = angle * CV_PI / 180;
//构造旋转矩阵
float roateMat[3][3] = {{cos(alpha), -sin(alpha), 0},{ sin(alpha),cos(alpha), 0},{0, 0, 1}};
int nSrcRows = src.rows;
int nSrcCols = src.cols;
//计算旋转以后图像矩阵的各个顶点位置
float a1 = nSrcCols * roateMat[0][0];
float b1 = nSrcCols * roateMat[1][0];
float a2 = nSrcCols * roateMat[0][0] + nSrcRows * roateMat[0][1];
float b2 = nSrcCols * roateMat[1][0] + nSrcRows * roateMat[1][1];
float a3 = nSrcRows * roateMat[0][1];
float b3 = nSrcRows * roateMat[1][1];
//计算出极值点
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);
cv::Mat dst(nRows, nCols, src.type(), cv::Scalar::all(0));
for (int i = 0; i < nRows; ++i)
{
for (int j = 0; j < nCols; ++j)
{
//旋转坐标转换
int x = (j + kxMin) * roateMat[0][0] - (i + kyMin) * roateMat[0][1];
int y = -(j + kxMin) * roateMat[1][0] + (i + kyMin) * roateMat[1][1];
//区域旋转
if ((x >= 0) && (x < nSrcCols) && (y >= 0) && (y < nSrcRows))
{
dst.at<cv::Vec3b>(i, j) = src.at<cv::Vec3b>(y, x);
}
}
}
return dst;
}
int main()
{
cv::Mat srcImage = cv::imread("C:\\Users\\LP\\Desktop\\C++\\ConsoleApplication4\\ConsoleApplication4\\1.jpg");
if(srcImage.empty())
{
return -1;
}
cv::imshow("原图像", srcImage);
int angle = 30;
//图像旋转操作
cv::Mat resultImage = angleRotatee(srcImage, angle);
cv::imshow("resultImage", resultImage);
cv::waitKey(0);
return 0;
}