OpenCV图像的旋转是通过图像的仿射变换来实现的,实现图像的旋转,分为三个步骤:
第一步:确定旋转角度和旋转中心。
第二步:确定旋转矩阵。通过getRotationMatrix2D函数计算出。
第三步:通过仿射变换实现旋转。通过warpAffine函数实现。
CV_EXPORTS_W Mat getRotationMatrix2D(Point2f center, double angle, double scale);
功能:计算一个二维旋转的仿射矩阵。
函数计算下面的矩阵:
[ [ α β ( 1 − α ) ⋅ center.x − β ⋅ center.y − β α β ⋅ center.x + ( 1 − α ) ⋅ center.y ] ] [\begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\ - \beta & \alpha & \beta \cdot \texttt{center.x} + (1- \alpha ) \cdot \texttt{center.y} \end{bmatrix}] [[α−ββα(1−α)⋅center.x−β⋅center.yβ⋅center.x+(1−α)⋅center.y]]
此处:
[ α = scale ⋅ cos angle , β = scale ⋅ sin angle ] [\begin{array}{l} \alpha = \texttt{scale} \cdot \cos \texttt{angle} , \\ \beta = \texttt{scale} \cdot \sin \texttt{angle} \end{array}] [α=scale⋅cosangle,β=scale⋅sinangle]
变换映射旋转中心是到中心自己本身,如果这个不是目标,调整偏移量。
参考 getAffineTransform, warpAffine, transform
CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst,
InputArray M, Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
功能:对一个图像实现一个仿射变换
当设置标志WARP_INVERSE_MAP 的时候,函数warpAffine变换使用以下的矩阵来实现一个仿射变换:
[ dst ( x , y ) = src ( M 11 x + M 12 y + M 13 , M 21 x + M 22 y + M 23 ) ] [\texttt{dst} (x,y) = \texttt{src} ( \texttt{M} _{11} x + \texttt{M} _{12} y + \texttt{M} _{13}, \texttt{M} _{21} x + \texttt{M} _{22} y + \texttt{M} _{23})] [dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23)]
否则,转换首先使用invertAffineTransform进行倒置,然后在上面的公式中代替M,函数不能就地转换。
参见warpPerspective, resize, remap, getRectSubPix, transform
#include
#include
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("D:\\OpenCVtest\\images\\juice.png", 1);
if (src.empty())
{
cout << "could not load image..." << endl;
return -1;
}
double rotate_angle = 15; //设置旋转的角度
Point2f rotate_center(src.rows / 2, src.cols / 2); // 设置旋转中心
Mat rotate_matrix = getRotationMatrix2D(rotate_center, rotate_angle, 1); //计算旋转矩阵
Size dstSize(src.cols, src.rows);
Mat image_dst;
warpAffine(src, image_dst, rotate_matrix, dstSize ); // 仿射变换
imshow("源图像", src);
imshow("仿射变换0", image_dst);
waitKey();
return 0;
}
运行结果:
#include
#include
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("D:\\OpenCVtest\\images\\juice.png", 1);
if (src.empty())
{
cout << "could not load image..." << endl;
return -1;
}
Size dstSize(src.cols, src.rows);
// 定义三个点
Point2f srcPoints[3];
Point2f dstPoints[3];
srcPoints[0] = Point2f(0, 0);
srcPoints[1] = Point2f(0, (float)(src.cols-1));
srcPoints[2] = Point2f(float(src.rows-1), (float)(src.cols - 1));
// 变换后的三个点
dstPoints[0] = Point2f((float)(src.rows)*0.15, (float)(src.cols)*0.25);
dstPoints[1] = Point2f((float)(src.rows) * 0.25, (float)(src.cols) * 0.65);
dstPoints[2] = Point2f((float)(src.rows) * 0.70, (float)(src.cols) * 0.70);
// 根据对应点求仿射矩阵
Mat rotate_matrx_1 = getAffineTransform(srcPoints, dstPoints);
Mat image_warp;
warpAffine(src, image_warp, rotate_matrx_1, dstSize);
imshow("源图像", src);
imshow("三点映射仿射变换", image_warp);
waitKey();
return 0;
}