首先我们来计算任一一点(x,y)绕其中点(xcenter,ycenter)经过角度sigma逆时针旋转后新坐标(x1,y1),我们假设图像的左上角为(left, top),右下角为(right, bottom),图像的宽为width,高为height,可得下列公式(具体推导见下面部分):
xcenter = (width+1)/2+left;
ycenter = (height+1)/2+top;
x1 = (x - xcenter) cosθ - (y - ycenter) sinθ + xcenter;
y1 = (x - xcenter) sinθ + (y - ycenter) cosθ + ycenter;
/****************************************************************************************************************************************************************************/
/* 公式推导*/
/****************************************************************************************************************************************************************************/
如图,我们假设点(x,y)位于角a处,(x1,y1)是由(x,y)绕原点(xcenter,ycenter)逆时针旋转θ
很容易得到:
xcenter = (width+1)/2+left;
ycenter = (height+1)/2+top;
我们知道点(x,y)和(x1,y1)都位于原点在(xcenter,ycenter),半径为r=dis(原点,(x,y))的圆上,则x,y我们可以表示成:
x = rcosa + xcenter;
y = rsina + ycenter;
x1 ,y1我们可以表示为:
x1 = rcos(a + θ )+ xcenter;
y1 = rsin( a + θ )+ ycenter;
x1 = rcosa*cosθ - rsina*cosθ + xcenter;
y1 = rsina*cosθ + rcosa*sinθ + ycenter;
将 x - xcenter = rcosa; y - ycenter = rsina带入上式得
x1 = (x - xcenter) cosθ - (y - ycenter) sinθ + xcenter;
y1 = (x - xcenter) sinθ + (y - ycenter) cosθ + ycenter;
得证
/*****************************************************************************************************************************************************************************/
知道上面的公式后,我们旋转图像就很简单了,直接利用opencv中的函数GetQuadrangleSubPix(提取象素四边形,使用子象素精度) 即可很快的得到旋转图像
/*******************************************************************/
GetQuadrangleSubPix
提取象素四边形,使用子象素精度
void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* map_matrix );
-
src
- 输入图像. dst
- 提取的四边形. map_matrix
- 3 × 2 变换矩阵 [A|b] (见讨论).
函数 cvGetQuadrangleSubPix 以子象素精度从图像 src 中提取四边形,使用子象素精度,并且将结果存储于 dst ,计算公式是:
dst(x + width(dst) / 2,y + height(dst) / 2) = src(A11x + A12y + b1,A21x + A22y + b2)
其中 A和 b 均来自映射矩阵(译者注:A, b为几何形变参数) ,映射矩阵为:
我们所有求的就是上述map_matrix矩阵中的各元素,旋转到这里就差不多了,接下来是缩放了
/***************************************************************************************************************/
图像的缩放:缩放我们将图像的任一点(x,y)同时乘以一个系数k即可,如果我们想在图像旋转的过程中同时进行图像的缩放,那么我们可以将系数因子k设置为f(θ)即:θ的函数