一、图像的旋转变换
1.1 图像旋转变换的理论
图像旋转变换是将一幅图像绕着某一点进行顺时针或逆时针方向旋转一定的角度,逆时针旋转为正,顺时针旋转为负。一般采用逆时针旋转。
1.2 图像旋转的步骤:
(1)平移坐标原点:将坐标原点平移到图像中心
(2)旋转:在新坐标原点的基础上进行坐标旋转
(3)平移坐标原点:将坐标原点平移回 屏幕的左上角
1.3 图像平移变换的矩阵表示
1.4 代码实现
主代码:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
// 函数声明
void ImgRotate(Mat& inputImag_1, Mat& outImage, double angle);
int main()
{
// 载入图像并显示
Mat originImage_boy = imread("lena.png", 1);
imshow("original_boy", originImage_boy);
// 创建效果图
Mat resultImage;
resultImage.create(originImage_boy.rows, originImage_boy.cols, originImage_boy.type());
// 记录时间
double timeClock = static_cast<double>(getTickCount());
// 函数调用
// 可定义和调用不同的函数
ImgRotate(originImage_boy, resultImage, 30);
// 输出时间
timeClock = ((double)getTickCount() - timeClock) / getTickCount();
cout << "run time:" << timeClock << "seconds" << endl;
imshow("result_Move",resultImage);
waitKey(0);
return 0;
}
1.4.1-OpenCV实现
实现思路:
使用OpenCV3中使用放射变换的相关函数:WarpAffine()函数
计算二维旋转变换矩阵:getRotationMatrix2D()函数
1.4.2-Rotate--version1.0---截掉旋转边缘
// 函数定义
// 使用动态地址计算图像
void ImgRotate01(Mat& inputImag_1, Mat& outputImag, double angle)
{
int rowsNum = inputImag_1.rows;
int colsNum = inputImag_1.cols;
outputImag = inputImag_1.clone();
// 获取图像中心
Point2f center;
center.x = colsNum / 2.0;
center.y = rowsNum / 2.0;
// 计算旋转矩阵
double scale = 1.0;
Mat rotate_mat = getRotationMatrix2D(center, -angle, scale);
// 放射变换
warpAffine(inputImag_1, outputImag, rotate_mat, Size(rowsNum, colsNum));
}
version1.0--实验结果:
1.4.2-Rotate--version2.0---扩大图像显出四角
// 函数定义
// 使用动态地址计算图像
void ImgRotate02(Mat& inputImag_1, Mat& outputImag, double angle)
{
// 获得输入图像大小
int rowsNum = inputImag_1.rows;
int colsNum = inputImag_1.cols;
outputImag = inputImag_1.clone();
// 获取图像中心
Point2f center;
center.x = colsNum / 2.0;
center.y = rowsNum / 2.0;
// 计算旋转矩阵
double scale = 1.0;
Mat rotate_mat = getRotationMatrix2D(center, -angle, scale);
// 计算旋转角度的正弦和余弦
double angleRotate = angle * CV_PI / 180.;
double fSina = sin(angleRotate) * scale;
double fCosb = cos(angleRotate) * scale;
// 计算新图像的大小
double new_colsNum = rowsNum * fabs(fSina) + colsNum * fabs(fCosb);
double new_rowsNum = colsNum * fabs(fSina) + rowsNum * fabs(fCosb);
// 计算旋转中的平移量
rotate_mat.at<double>(0, 2) += cvRound((new_colsNum - colsNum) / 2);
rotate_mat.at<double>(1, 2) += cvRound((new_rowsNum - rowsNum ) / 2);
// 放射变换得到结果图
warpAffine(inputImag_1, outputImag, rotate_mat, Size(new_colsNum, new_rowsNum));
}
version2.0--实验结果: