已知三点在两个坐标系中的坐标,求两个坐标系的转换关系

数学模型

已知两个坐标系在各方向上尺度缩放比例一致,两个坐标系的转换关系可以用7个参数来表示,3个旋转参数,3个平移参数,1个比例参数。已知三点在A、B两个坐标系中的坐标,那么这7个参数可以唯一确定。

坐标转换的数学模型为:

image.png

其中,λ是比例参数,R是旋转矩阵,Δ是平移向量,A、B分别是两个坐标系中的坐标。

比例参数λ最容易计算

image.png

image.png

旋转矩阵R是一个3x3的正交矩阵,有3个自由度。可利用反对称矩阵S来构造旋转矩阵R:

image.png

那么

image.png

其中I是单位矩阵,这里R只有a、b、c三个变量,解出a、b、c即可确定旋转矩阵R。

image.png

这样(3)式可写为

image.png

整理可得

image.png

把a、b、c带入(2)式可到旋转矩阵R,把任意一点坐标带入(1)式可得Δ。

swift算法实现

在ARKit中,SCNNode.transform是一个4x4的变换矩阵,

image.png

下面代码中的m_Translation为λT,m_Rotation为λR

声明变量

    var point1onA: float3 = float3(0,0,0)
    var point2onA: float3 = float3(0,0,0)
    var point3onA: float3 = float3(0,0,0)
    
    var point1onB: float3 = float3(0,0,0)
    var point2onB: float3 = float3(0,0,0)
    var point3onB: float3 = float3(0,0,0)
    
    var m_ratio: Float = 0.0 // 比例参数λ
    var m_Translation: float3 = float3(0,0,0) // λx平移向量Δ,3个参数
    var m_Rotation: matrix_float3x3! // λx旋转矩阵R ,3个参数abc,计算时解算的是abc

计算比例参数λ,为了减少误差取平均值

func caliratio(){
        var ratiotemp:[Float] = [0.0,0.0,0.0]
        var temp1:Float = 0.0
        var temp2:Float = 0.0
        
        temp1 = distance(point1onA, point2onA)
        temp2 = distance(point1onB, point2onB)
        ratiotemp[0] = temp1/temp2
        
        temp1 = distance(point2onA, point3onA)
        temp2 = distance(point2onB, point3onB)
        ratiotemp[1] = temp1/temp2
        
        temp1 = distance(point1onA, point3onA)
        temp2 = distance(point1onB, point3onB)
        ratiotemp[2] = temp1/temp2
        
        m_ratio = (ratiotemp[0]+ratiotemp[1]+ratiotemp[2])/3
    }

计算旋转矩阵R

func caliRotation(){ 
        //2点减1点
        let m12 = (point2onA.z - point1onA.z) + m_ratio*(point2onB.z - point1onB.z)
        
        let m32 = (point2onA.x - point1onA.x) + m_ratio*(point2onB.x - point1onB.x)

        let m31 = (point2onA.y - point1onA.y) + m_ratio*(point2onB.y - point1onB.y)
    
        let m21 = m12        
        //3点减1点
        let m23 = (point3onA.x - point1onA.x) + m_ratio*(point3onB.x - point1onB.x)
        
        let m13 = (point3onA.y - point1onA.y) + m_ratio*(point3onB.y - point1onB.y)
        
        
        let J = matrix_float3x3(float3(0,-m12,m13),float3(-m21,0,m23),float3(-m31,m32,0))

        let K = J.inverse      
        
        var xyz = float3(0,0,0)
        
        xyz.x = -1 * m_ratio*(point2onA.x - point1onA.x) + (point2onB.x - point1onB.x)
        
        xyz.y = -1 * m_ratio*(point2onA.y - point1onA.y) + (point2onB.y - point1onB.y)
        
        xyz.z = -1 * m_ratio*(point3onA.z - point1onA.z) + (point3onB.z - point1onB.z)
        
        let abc = K * xyz        
 
        let S = matrix_float3x3(float3(0, abc.z, abc.y), float3(-1*abc.z, 0, abc.x), float3(-1*abc.y, -1*abc.x, 0))
        
        let I = matrix_float3x3(float3(1,0,0), float3(0,1,0), float3(0,0,1))
        
        
         m_Rotation = (I + S) * ((I - S).inverse) * m_ratio    }

计算偏移量

 func caliTranslation(){
       m_Translation = point3onA - m_Rotation * point3onB    }

测试

func test(){
    
     point1onA = float3(1,0,0)
     point2onA = float3(0,1,0)
     point3onA = float3(0,0,1)
    
     let node = SCNNode()
     node.position = SCNVector3(0.1, 0.2, 0.3)
     node.eulerAngles = SCNVector3(0.1, 0.2, 0.3)
     node.scale = SCNVector3(1.2, 1.2, 1.2)
        
     let newA = node.convertPosition(SCNVector3(point1onA), from: nil)
     let newB = node.convertPosition(SCNVector3(point2onA), from: nil)
     let newC = node.convertPosition(SCNVector3(point3onA), from: nil)
        
     point1onB = float3(newA.x, newA.y, newA.z)
     point2onB = float3(newB.x, newB.y, newB.z)
     point3onB = float3(newC.x, newC.y, newC.z)
        
     caliratio()
     caliRotation()
     caliTranslation()
        
     print("比例参数λ:\(m_ratio)")
     print("平移向量Δ:\(m_Translation)")
     print("旋转矩阵R:\(m_Rotation)")
     print("变换矩阵真值:node.transform")

    }



作者:梁间
链接:https://www.jianshu.com/p/58cf5655f9a9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864