【问题标题】:3D rotation matrix between two 3D points两个 3D 点之间的 3D 旋转矩阵
【发布时间】:2015-07-16 13:59:54
【问题描述】:

我有 2 个已知的 3d 点 OC1 和 OC2,它们是空间中 2 轴图的原点,我需要计算它们之间的 3D 旋转矩阵。

我知道使用 R1&T1 可以到达 Oc1,使用 R2&T2 我可以到达 Oc2,但我需要计算 Oc1 和 Oc2 之间的 3D 旋转矩阵。我刚刚想到了这个规则:

oMc1=(R1 | T1) and oMc2=(R2 | T2) and what I want is:
c1Mc2 = (oMc1)^-1 oMc2

所以我尝试实现它,这是我的代码:

    vector <Point3f> listOfPointsOnTable;
    cout << "******** DATA *******" << endl;
    listOfPointsOnTable.push_back(Point3f(0,0,0));
    listOfPointsOnTable.push_back(Point3f(100,0,0));
    listOfPointsOnTable.push_back(Point3f(100,100,0));
    listOfPointsOnTable.push_back(Point3f(0,100,0));

    cout << endl << "Scene points :" << endl;
    for (int i = 0; i < listOfPointsOnTable.size(); i++)
    {
        cout << listOfPointsOnTable[i] << endl;
    }

    //Define the optical center of each camera
    Point3f centreOfC1 = Point3f(23,0,50);
    Point3f centreOfC2 = Point3f(0,42,20);
    cout << endl << "Center Of C1: " << centreOfC1 << " , Center of C2 : " << centreOfC2 << endl;

    //Define the translation and rotation between main axis and the camera 1 axis
    Mat translationOfC1 = (Mat_<double>(3, 1) << (0-centreOfC1.x), (0-centreOfC1.y), (0-centreOfC1.z));
    float rotxC1 = 0, rotyC1 = 0, rotzC1 = -45;
    int focaleC1 = 2;
    Mat rotationOfC1 = rotation3D(rotxC1, rotyC1,rotzC1);
    cout << endl << "Translation from default axis to C1: " << translationOfC1 << endl;
    cout << "Rotation from default axis to C1: " << rotationOfC1 << endl;
    Mat transformationToC1 = buildTransformationMatrix(rotationOfC1, translationOfC1);
    cout << "Transformation from default axis to C1: " << transformationToC1 << endl << endl;

    //Define the translation and rotation between main axis and the camera 2 axis
    Mat translationOfC2 = (Mat_<double>(3, 1) << (0-centreOfC2.x), (0-centreOfC2.y), (0-centreOfC2.z));
    float rotxC2 = 0, rotyC2 = 0, rotzC2 = -90;
    int focaleC2 = 2;
    Mat rotationOfC2 = rotation3D(rotxC2, rotyC2,rotzC2);
    cout << endl << "Translation from default axis to C2: " << translationOfC2 << endl;
    cout << "Rotation from default axis to C2: " << rotationOfC2 << endl;
    Mat transformationToC2 = buildTransformationMatrix(rotationOfC2, translationOfC2);
    cout << "Transformation from default axis to C2: " << transformationToC2 << endl << endl;

    Mat centreOfC2InMat = (Mat_<double>(3, 1) << centreOfC2.x, centreOfC2.y, centreOfC2.z);
    Mat centreOfC2InCamera1 = rotationOfC1 * centreOfC2InMat + translationOfC1;
    Mat translationBetweenC1AndC2 = -centreOfC2InCamera1;
    cout << endl << "****Translation from C2 to C1" << endl;
    cout << translationBetweenC1AndC2 << endl;
    Mat centreOfC1InMat = (Mat_<double>(3, 1) << centreOfC1.x, centreOfC1.y, centreOfC1.z);
    Mat centreOfC1InCamera2 = rotationOfC2 * centreOfC1InMat + translationOfC2;
    Mat translationBetweenC2AndC1 = -centreOfC1InCamera2;
    cout << "****Translation from C1 to C2" << endl;
    cout << translationBetweenC2AndC1 << endl;

    cout << "Tran1-1 * Trans2 = " << transformationToC1.inv() * transformationToC2 << endl;
    cout << "Tran2-1 * Trans1 = " << transformationToC2.inv() * transformationToC1 << endl;

Mat rotation3D(int alpha, int beta, int gamma)
{
    // Rotation matrices around the X, Y, and Z axis
    double alphaInRadian = alpha * M_PI / 180.0;
    double betaInRadian = beta * M_PI / 180.0;
    double gammaInRadian = gamma * M_PI / 180.0;
    Mat RX = (Mat_<double>(3, 3) <<
                  1,          0,           0,
                  0, cosf(alphaInRadian), sinf(alphaInRadian),
                  0, -sinf(alphaInRadian),  cosf(alphaInRadian));
    Mat RY = (Mat_<double>(3, 3) <<
                  cosf(betaInRadian), 0, sinf(betaInRadian),
                  0, 1,          0,
                  -sinf(betaInRadian), 0,  cosf(betaInRadian));
    Mat RZ = (Mat_<double>(3, 3) <<
                  cosf(gammaInRadian), sinf(gammaInRadian), 0,
                  -sinf(gammaInRadian),cosf(gammaInRadian), 0,
                  0,          0,           1);
    // Composed rotation matrix with (RX, RY, RZ)
    Mat R = RX * RY * RZ;
    return R;
}
Mat buildTransformationMatrix(Mat rotation, Mat translation)
{
    Mat transformation = (Mat_<double>(4, 4) <<
                          rotation.at<double>(0,0), rotation.at<double>(0,1), rotation.at<double>(0,2), translation.at<double>(0,0),
                          rotation.at<double>(1,0), rotation.at<double>(1,1), rotation.at<double>(1,2), translation.at<double>(1,0),
                          rotation.at<double>(2,0), rotation.at<double>(2,1), rotation.at<double>(2,2), translation.at<double>(2,0),
                          0, 0, 0, 1);

    return transformation;
}

这是输出:

//Origin of 3 axis     
O(0,0,0), OC1 (23, 0, 50), OC2 (0, 42, 20)

Translation from default axis to OC1: [-23;
 0;
 -50]
Rotation from default axis to OC1: [0.7071067690849304, -0.7071067690849304, 0;
 0.7071067690849304, 0.7071067690849304, 0;
 0, 0, 1]
Trans1 = Transformation from default axis to OC1: [0.7071067690849304, -0.7071067690849304, 0, -23;
 0.7071067690849304, 0.7071067690849304, 0, 0;
 0, 0, 1, -50;
 0, 0, 0, 1]

Translation from default axis to OC2: [0;
 -42;
 -20]
Rotation from default axis to OC2: [-4.371138828673793e-08, -1, 0;
 1, -4.371138828673793e-08, 0;
 0, 0, 1]
Trans2 = Transformation from default axis to OC2: [-4.371138828673793e-08, -1, 0, 0;
 1, -4.371138828673793e-08, 0, -42;
 0, 0, 1, -20;
 0, 0, 0, 1]

(Trans1)-1 * (Trans2) = [0.7071067623795453, -0.7071068241967844, 0, -13.43502907247513;
 0.7071068241967844, 0.7071067623795453, 0, -45.96194156373071;
 0, 0, 1, 30;
 0, 0, 0, 1]
(Trans2)-1 * (Trans1) = [0.7071067381763105, 0.7071067999935476, 0, 42.00000100536185;
 -0.7071067999935475, 0.7071067381763104, -0, 22.99999816412165;
 0, 0, 1, -30;
 0, 0, 0, 1]

//Calculation of translation between OC1 and OC2:
****Translation from C2 to C1
[52.69848430156708;
 -29.69848430156708;
 30]
****Translation from C1 to C2
[1.005361930594972e-06;
 19;
 -30]

如你所见,(Trans1)-1 * (Trans2) 的第 4 列既不等于 C2-&gt;C1 的翻译也不等于 C2-&gt;C1 的翻译

它让我觉得c1Mc2 = (oMc1)^-1 oMc2 没有得到我想要的,但我真的不明白为什么?有没有其他解决方案可以得到我想要的?

【问题讨论】:

    标签: opencv 3d rotation


    【解决方案1】:

    Oc1 的旋转矩阵定义为局部 XYZ 轴的分量:

          | Xc1[0] Yc1[0] Zc1[0] |
    R_1 = | Xc1[1] Yc1[1] Zc1[1] |
          | Xc1[2] Yc1[2] Zc1[2] |
    

    对于R_2Oc2 也是如此。

    如果它们之间的相对旋转是R那么你可以定义

    R_2 = R_1*R
    

    因此:

    R = transpose(R_1)*R_2
    

    这就是你所需要的。

    【讨论】:

    • 翻译怎么样?与最初的问题标题相反,我相信 OP 正在寻找变换,而不仅仅是旋转。
    • @ja72,感谢您的回答。但是我并没有真正理解“Xc1 [0],Xc1 [1],Xc1 [2]”的意思吗?你能澄清一下吗?
    • @MarkMiller,我已经在代码中发布了如何计算 OC1 和 OC2 之间的转换。
    • Xc1在世界坐标中有三个分量,它们是Xc1[0]Xc1[1]Xc1[2]
    • 标题要求旋转矩阵。您首先处理平移,然后处理旋转。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    • 2017-12-21
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    相关资源
    最近更新 更多