源码
cv::Mat cv::getRotationMatrix2D( Point2f center, double angle, double scale )
{ angle *= CV_PI/180; double alpha = cos(angle)*scale; double beta =
sin(angle)*scale; Mat M(2, 3, CV_64F); double* m = M.ptr<double>(); m[0] =
alpha; m[1] = beta; m[2] = (1-alpha)*center.x - beta*center.y; m[3] = -beta;
m[4] = alpha; m[5] = beta*center.x + (1-alpha)*center.y; return M; }
推导

1、有图有真相

为什么这样画图,值得注意的是,计算机中图像的横坐标是向右增加,纵坐标是向下增加!!!

2、任务描述

其中角DAB=α,角CAB=θ

AD与横坐标轴平行,AE与纵坐标轴平行,现在需要沿着A点(centerX,centerY)==>>简写(cx,cy)作为旋转中心

将B点旋转θ角度后到达C点,假设C点坐标为(x',y'),求解x',y'和x,y,θ,cx,cy的数学关系

3、开始计算

AC由AB旋转得到,故其长度相等,令AC=AB=L

于是由三角函数知识

x'=cx+L*cos(α-θ)=cx+L*(cos(α)*cos(θ)+sin(α)*sin(θ))     1式

y'=cy+L*sin(α-θ)=cy+L*(sin(a)*cos(θ)-sin(θ)*cos(a))       2式

cos(α)=(x-cx)/L                                                               
 3式

sin(a)=(y-cy)/L                                                               
  4式

把3式,4式分别代入1式和2式,可以消去α和L。得到

x'=cx+(x-cx)*cos(θ)+(y-cy)*sin(θ)=x*cos(θ)+y*sin(θ)+cx*(1-cos(θ))-cy*sin(θ)

y'=cy+(y-cy)*cos(θ)-(x-cx)*sin(θ)=x*(-sin(θ))+y*cos(θ)+cy*(1-cos(θ))+cx*sin(θ)

提取出矩阵就是

[

        [cos(θ),sin(θ),cx*(1-cos(θ))-cy*sin(θ)],

        [-sin(θ),cos(θ),cy*(1-cos(θ))+cx*sin(θ)]

]

验证

实践是检验真理的唯一标准

上Python代码
import numpy as np import cv2 as cv import math cx = 250 cy = 250 angle = 45
scale = 1.0 opencv_M = cv.getRotationMatrix2D((cx, cy), angle, scale)
print(f"opencv_M=\n{opencv_M}") print("=================================")
cos_angle = math.cos(angle / 180.0 * math.pi) sin_angle = math.sin(angle /
180.0 * math.pi) self_M = np.array([ [cos_angle, sin_angle, cx * (1 -
cos_angle) - cy * sin_angle], [-sin_angle, cos_angle, cy * (1 - cos_angle) + cx
* sin_angle] ]) print(f"self_M=\n{self_M}")
旋转中心(cx,cy)=(250,250)

旋转角度θ=45°

不进行缩放操作scale=1.0

运行结果

可以看出,运算结果是一模一样的,此函数的运算过程确实如上述公式所示

注意

python中math函数库的三角函数输入参数,是转换成多少pi,而不是直接输入一个角度,(准确地说,它接受的是弧度)

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信