opencv基础:罗德里格斯旋转公式(Rodrigues' rotation formula)推导 rodrigues()函数原理

参考:1—https://openhome.cc/Gossip/WebGL/Rodrigues.html(比较好的理解流程)
2—https://www.cnblogs.com/wtyuan/p/12324495.html(推导出旋转矩阵R)
建议看原链接!!
具体如下:


        <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">在〈</font></font><a href="TransformationMatrix.html"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">转换矩阵</font></font></a><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">〉中谈到的旋转,是顶点绕着X、Y或Z轴转动,然而有时会需要绕着指定的特定轴来旋转顶点,轴的部份会使用向量来表示,例如下图,使用u来表示旋转轴,旋转角度为θ:</font></font></p>

Rodrigues 旋转公式

如果对于3D方面的数学有些涉猎,看到这个需求应该会想到四元数与旋转,就结论来说,可以将这个需求化为一个四元数,然而套用四元数旋转矩阵,就可以达成任务,然而,若你对四元数或其旋转矩阵的导证有兴趣,认识Rodrigues旋转公式的导证,会有所帮助。

首先,旋转时的圆路径构成一个平面,该平面与u 正交,把这个平面置于原点,若未旋转的顶点使用向量v 来表示,可以将之分解为两个向量v1、v2:

Rodrigues 旋转公式

v1为v在u上的投影,而v2为v在平面上的投影,a为v1、v2的夹角,根据内积公式u‧v = |u||v| cos(a),若要求得v1可以如下:

Rodrigues 旋转公式

实际上对于旋转轴u,只需关心它的方向,不用在意它的大小,因此u 可以用单位向量指定,也就是|u| 会是1,结果就是:

Rodrigues 旋转公式

接下来要绕着u 旋转v 得到v',就可以看成是v1 与v2 绕着u 旋转,若旋转后分别得到v1' 与v2',最后得到v' = v1' + v2':

Rodrigues 旋转公式

对于v1 来说,因为跟u 平行,旋转后还是相同,也就是v1' = v1,至于v2 的转动,可以分解为平面上的两个向量:

Rodrigues 旋转公式

为了能计算v2' 在上图中垂直轴上的投影,必须要有垂直轴的向量w,因为指定的旋转轴u 与v2 正交,那么w 可以由u 与v2 的外积取得,也就是w = ux v2,单位向量为w/|w|,因此v21' 与v22' 会是:

Rodrigues 旋转公式

因为|v2'| 就是|v2|,因此:

Rodrigues 旋转公式

外积公式a x b = |a||b|sin(a) n,n为与a、b正交的单位向量,在这边a为u,b为v2,而u与v2正交,因此ux v2 = |u||v2| n,n就是w/| w|,因此|w|就是|u||v2|w / (ux v2),u是单位向量,|u|为1,因此|w|为|v2|w / (ux v2),代入上面的式子化简后得到:

Rodrigues 旋转公式

因此v2' = v21' + v22' = sin(θ)(ux v2) + cos(θ)v2,其中ux v2 可以是ux (v - v1) = uxv - ux v1,因为u 与v1 平行,ux v1为0,所以ux v2 会是uxv,最后就是v2' = sin(θ)(uxv) + cos(θ)v2。

因为v旋转后得到v' = v1' + v2',前面已导出v1' = v1,而v1 = (u‧v) u,v2 = v - (u‧v) u,因此
v'为(u‧ v) u + sin(θ)(uxv) + cos(θ)(v - (u‧v) u),整理一下可以得到最后的旋转公式:

Rodrigues 旋转公式

公式是导出来了,不过看起来复杂,有个轴角(axis–angle)转换矩阵与要转动的向量结合后,等价于此公式,不过矩阵相对于四元数旋转矩阵来说,还是复杂许多,因而比较少见到这个公式的运用或实作。

不过,利用分解向量以及有些向量之间的正交关系,来导证出旋转公式的过程,与导证四元数旋转矩阵的过程会有关联,这之后再来简单聊聊!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: opencv中的mat::zeros函数是用来创建一个指定大小和类型的全零矩阵的函数。它的语法如下: cv::Mat cv::Mat::zeros(int rows, int cols, int type) 其中,rows和cols分别表示矩阵的行数和列数,type表示矩阵的类型,可以是CV_8UC1、CV_8UC3、CV_32FC1等等。函数返回一个指定大小和类型的全零矩阵。 ### 回答2: opencv中的mat::zeros函数是一个用于创建一个指定大小和类型的矩阵的函数。该函数的原型如下: Mat cv::Mat::zeros(int rows, int cols, int type) 其中,rows表示矩阵的行数,cols表示矩阵的列数,type表示矩阵的数据类型,常用的数据类型包括CV_8U、CV_8S、CV_16U、CV_16S、CV_32S、CV_32F、CV_64F等。该函数返回一个新创建的矩阵,初始化所有元素为0。 使用Mat::zeros函数可以快速创建一个指定大小和类型的矩阵,并且初始化为0,而不用手动遍历矩阵并设置每个元素的值。这在一些图像处理的操作中非常有用,例如在创建掩膜矩阵时,可以使用该函数创建一个大小和图像一样的全零矩阵,然后在需要的位置设置为1或其他值。 下面是一个示例代码,使用mat::zeros函数创建了一张大小为512x512,类型为CV_8UC1的全零图像: Mat img = Mat::zeros(512, 512, CV_8UC1); 需要注意的是,mat::zeros函数创建的矩阵所有元素的值都是0,而不是默认值。如果需要创建一个矩阵并且初始化为其它默认值,可以使用其重载函数,例如: Mat img = Mat::zeros(512, 512, CV_8UC3); Mat img2 = Mat::zeros(Size(512, 512), CV_8UC3); Mat img3 = Mat::zeros(img.size(), img.type()); 其中,img2使用了Size类型来指定矩阵的大小,img3则使用现有的矩阵来指定矩阵的大小和类型。 ### 回答3: opencv中的mat::zeros函数是用于创建一个具有指定行数、列数和类型的矩阵,并将所有像素的值设置为0的函数。这个函数可以创建单通道或多通道的矩阵,可以是8位、16位、32位或64位浮点型,也可以是8位、16位或32位整数型。该函数返回一个与所创建矩阵相同类型的空矩阵。 该函数有两种格式,第一种格式是: Mat dst = Mat::zeros(int rows, int cols, int type); 参数说明: rows:矩阵的行数; cols:矩阵的列数; type:矩阵的类型,包括如下几种: CV_8U:8位无符号整数型; CV_8S:8位有符号整数型; CV_16U:16位无符号整数型; CV_16S:16位有符号整数型; CV_32S:32位有符号整数型; CV_32F:32位浮点型; CV_64F:64位浮点型。 第二种格式是: void cv::Mat::zeros(InputArray _src, Scalar value=Scalar::all(0)) 参数说明: _src:矩阵,用于接收零矩阵; value:可选的参数,用于设置矩阵像素的值,默认值为Scalar::all(0),即所有像素设置为0。 总之,mat::zeros函数是一种非常方便的创建空矩阵并初始化像素值的方法。它可以用于图像处理、计算机视觉、机器学习等众多领域。在许多opencv应用中,需要先创建一个空矩阵,并将其作为输出参数传递给其他函数。因此,mat::zeros函数可以简化代码,提高开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值