版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YunLaowang/article/details/86539910
原理
使用warpAffine()进行图像旋转,是基于仿射变换的原理,通常2
3矩阵进行仿射变换:
对于二维矩阵:
进行如下变换:
等价于:
其中:
在已知 和 的情况下,还需要使用如下函数获取变换矩阵 :
//scale为缩放因子,angle为旋转角度(正:逆时针),(centerx,centery)为旋转中心
getRotationMatrix2D(Point2f center, double angle, double scale)
矩阵 定义:
防止切边
- 为防止原图在旋转之后被切边,需要对getRotationMatrix2D得到的仿射变换矩阵 进行一定的修改,具体是通过修改 矩阵中的平移部分: 和 完成;
- 思路:先计算out_img的图像尺寸(rotated_width和rotated_height),然后将旋转之后的图像中心由center平移至out_img中心。
- 方法:见如下代码
// 防止切边,对平移矩阵B进行修改
rotate_matrix.at<double>(0, 2) += (rotated_width - src.cols) / 2;
rotate_matrix.at<double>(1, 2) += (rotated_height - src.rows) / 2;
完整代码
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat src = imread("pic.jpg");
if (src.empty())
{
cout << "The image is empty, please check it!" << endl;
return 0;
}
Mat out_img;
// 旋转角度
double angle = 45.0;
// 计算旋转后输出图形的尺寸
int rotated_width = ceil(src.rows * fabs(sin(angle * CV_PI / 180)) + src.cols * fabs(cos(angle * CV_PI / 180)));
int rotated_height = ceil(src.cols * fabs(sin(angle * CV_PI / 180)) + src.rows * fabs(cos(angle * CV_PI / 180)));
// 计算仿射变换矩阵
Point2f center(src.cols / 2, src.rows / 2);
Mat rotate_matrix = getRotationMatrix2D(center, 45, 1.0);
// 防止切边,对平移矩阵B进行修改
rotate_matrix.at<double>(0, 2) += (rotated_width - src.cols) / 2;
rotate_matrix.at<double>(1, 2) += (rotated_height - src.rows) / 2;
// 应用仿射变换
warpAffine(src, out_img, rotate_matrix, Size(rotated_width, rotated_height), INTER_LINEAR, 0, Scalar(255, 255, 255));
imshow("case1r", out_img);
waitKey();
return 0;
}
结果:
参考链接:仿射变换