OpenCV局部坐标系和世界坐标系转换

本文实现局部坐标系和世界坐标系的转换。

1.局部坐标系->世界坐标系

假设机器在p1处在世界坐标系下的位姿为(x,y,z,θ)=(1,1,0,0),p1 和p2之间的转换(局部坐标系)为t12表示为(1,1,0,45),
求p2处世界坐标系下的位姿(x,y,z,θ)?
结果为(2,2,0,45)
程序如下:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

void set_pose_by_R_t( Mat R, Mat t,Mat& T)
{
    Mat tmpT = cv::Mat::eye(4,4,R.type());
    R.copyTo(tmpT.rowRange(0,3).colRange(0,3));
    t.copyTo(tmpT.rowRange(0,3).col(3));
    T=tmpT.clone();
}
void get_pose_R_t(Mat T,Mat& R, Mat& t)
{
    R=Mat::zeros(3,3,T.type());
    t=Mat::zeros(3,1,T.type());
    T.rowRange(0,3).colRange(0,3).copyTo(R);
    T.rowRange(0,3).col(3).copyTo(t);
}
int main()
{
    //1.p1 world position expression by opencv
    cv::Mat p1rvec = (cv::Mat_<float>(3, 1) << 0,0,0);
    Mat p1R;
    Rodrigues(p1rvec*CV_PI / 180,p1R);
    cv::Mat p1t = (cv::Mat_<float>(3, 1) << 1, 1, 0);
    Mat p1T;
    set_pose_by_R_t(p1R,p1t,p1T);
    cout<<p1T<<endl;

    //2. t12 value
    cv::Mat t12rvec = (cv::Mat_<float>(3, 1) << 0,0,45);
    Mat t12R;
    Rodrigues(t12rvec*CV_PI / 180,t12R);
    cv::Mat t12t = (cv::Mat_<float>(3, 1) << 1, 1, 0);
    Mat t12T;
    set_pose_by_R_t(t12R,t12t,t12T);
    cout<<t12T<<endl;

    //3.calculate p2 world positon by opencv
    //3.1 calculate by 3*3 matrix  p2Rcv=p1R*t12R;;  p2tcv=p1R*t12t+p1t;
    Mat p2Rcv=p1R*t12R;
    Mat p2tcv=p1R*t12t+p1t;
    Mat p2Tcv;
    set_pose_by_R_t(p2Rcv,p2tcv,p2Tcv);
    cout<<p2Tcv<<endl;
    Mat p2rvec;
    Rodrigues(p2Rcv, p2rvec);
    p2rvec=p2rvec*180/ CV_PI;
    cout<<"p2 R"<<p2rvec<<endl;
    cout<<"p2 t"<<p2tcv<<endl;

    //3.2 calculate by 4*4 matrix  p2T=p1T*T12;
    Mat p2T=p1T*t12T;
    Mat p2Rcv2;
    Mat p2tcv2;
    get_pose_R_t(p2T,p2Rcv2,p2tcv2);

    cout<<"4*4T"<<p2T<<endl;
    Mat p2rvec2;
    Rodrigues(p2Rcv2, p2rvec2);
    p2rvec2=p2rvec2*180/ CV_PI;
    cout<<"4*4 p2 R"<<p2rvec2<<endl;
    cout<<"4*4 p2 t"<<p2tcv2<<endl;
    return 0;
}

2.世界坐标系->局部坐标系

假设机器在p1处在世界坐标系下的位姿为(x,y,z,θ)=(1,1,0,0),p2处世界坐标系下的位姿(x,y,z,θ)=(2,2,0,45)
求p1 和p2之间的转换t12。
程序如下:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

void set_pose_by_R_t( Mat R, Mat t,Mat& T)
{
    Mat tmpT = cv::Mat::eye(4,4,R.type());
    R.copyTo(tmpT.rowRange(0,3).colRange(0,3));
    t.copyTo(tmpT.rowRange(0,3).col(3));
    T=tmpT.clone();
}
void get_pose_R_t(Mat T,Mat& R, Mat& t)
{
    R=Mat::zeros(3,3,T.type());
    t=Mat::zeros(3,1,T.type());
    T.rowRange(0,3).colRange(0,3).copyTo(R);
    T.rowRange(0,3).col(3).copyTo(t);
}
int main()
{
    //1.p1 world position expression by opencv
    cv::Mat p1rvec = (cv::Mat_<float>(3, 1) << 0,0,0);
    Mat p1R;
    Rodrigues(p1rvec*CV_PI / 180,p1R);
    cv::Mat p1t = (cv::Mat_<float>(3, 1) << 1, 1, 0);
    Mat p1T;
    set_pose_by_R_t(p1R,p1t,p1T);
    cout<<p1T<<endl;

    //2.p2 world position
    cv::Mat p2rvec = (cv::Mat_<float>(3, 1) << 0,0,45);
    Mat p2R;
    Rodrigues(p2rvec*CV_PI / 180,p2R);
    cv::Mat p2t = (cv::Mat_<float>(3, 1) << 2, 2, 0);
    Mat p2T;
    set_pose_by_R_t(p2R,p2t,p2T);
    cout<<p2T<<endl;

    //3.calculate t12
    Mat t12T=p1T.inv()*p2T;
     cout<<t12T<<endl;
    Mat t12R;
    Mat t12t;
     get_pose_R_t(t12T,t12R,t12t);
    Mat t12rvec;
    Rodrigues(t12R, t12rvec);
    t12rvec=t12rvec*180/ CV_PI;
    cout<<"t12rvec"<<t12rvec<<endl;
    cout<<"t12t"<<t12t<<endl;
    return 0;
}
### 回答1: 要将一个点从局部坐标系转换世界坐标系,需要进行以下步骤: 1. 获取局部坐标系世界坐标系的变换矩阵。这个变换矩阵是将一个点从局部坐标系转换世界坐标系所需的变换操作。在OpenCASCADE中,可以通过使用gp_Trsf类来创建和操作变换矩阵。 2. 创建一个包含局部坐标系下点的几何对象。在OpenCASCADE中,可以使用gp_Pnt类来表示一个点的坐标。使用这个类可以创建一个局部坐标系下的点。 3. 应用变换矩阵将局部坐标系下的点转换世界坐标系下的点。这可以通过将局部坐标系下的点与变换矩阵相乘得到。在OpenCASCADE中,可以使用gp_GTrsf类来进行点与变换矩阵的乘法操作。 4. 获取世界坐标系下点的坐标值。这就是转换后的点在世界坐标系下的坐标值。在OpenCASCADE中,可以通过使用gp_Pnt类的GetX(), GetY()和GetZ()函数来获取点的坐标值。 总结起来,将一个点从局部坐标系转换世界坐标系,需要获取局部坐标系世界坐标系的变换矩阵,并应用这个变换矩阵将局部坐标系下的点转换世界坐标系下的点,最后获取转换后点的坐标值。 ### 回答2: 在使用OpenCascade时,如果已知一个点在局部坐标系中的坐标值,可以通过以下方法计算其在世界坐标系下的坐标值: 1. 首先,需要建立一个坐标转换对象。OpenCascade提供了gp_Trsf类来表示坐标转换。可以使用gp_Trsf类的构造函数创建一个初始的坐标转换对象。 2. 通过使用gp_Trsf类的方法来定义坐标转换对象的转换规则。常用的转换规则包括平移、旋和缩放。 3. 使用gp_Trsf类的方法将转换规则应用到点的坐标值上。可以使用gp_Pnt类来表示点的坐标值。通过gp_Trsf类的Transform方法,可以将点的坐标值应用到坐标转换对象上,从而得到点在世界坐标系下的坐标值。 总结起来,使用OpenCascade计算点从局部坐标系世界坐标系坐标值的步骤如下: 1. 创建一个初始的gp_Trsf对象。 2. 使用gp_Trsf对象的方法定义坐标转换规则。 3. 使用gp_Trsf对象的Transform方法将点的坐标值从局部坐标系转换世界坐标系。 需要注意的是,上述方法仅适用于单个点的坐标转换。如果涉及到多个点的坐标转换,可以按照相同的方法依次将每个点的坐标值进行转换。 ### 回答3: 要计算一个点在世界坐标系中的坐标值,需要知道该点相对于局部坐标系的位置和姿态信息,以及局部坐标系相对于世界坐标系的位置和姿态信息。 在OpenCascade中,可以通过以下步骤计算一个点在世界坐标系中的坐标值: 1. 获取局部坐标系相对于世界坐标系的位置和姿态信息。这可以通过获取局部坐标系的变换矩阵来实现。可以使用OpenCascade提供的接口函数来获取坐标系的变换矩阵,如gp_Trsf或TopLoc_Location。 2. 获取点在局部坐标系中的坐标值。可以通过点的坐标来表示,或者通过一个带有位置信息的几何体对象来表示。 3. 将点的坐标转换为齐次坐标。齐次坐标是一种表示三维点的方法,可以通过将点的坐标值添加一个额外的参数来表示,通常为1。 4. 使用局部坐标系的变换矩阵对点进行变换。可以通过矩阵乘法将点的齐次坐标坐标系的变换矩阵相乘,得到点在世界坐标系中的齐次坐标。 5. 将点的齐次坐标转换为三维坐标。可以通过将齐次坐标除以其最后一个参数的值来得到点的世界坐标值。 通过以上步骤,就可以计算得到一个点在世界坐标系中的坐标值。在OpenCascade中,可以使用相应的接口函数,如gp_Pnt,来表示和操作点的坐标
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值