11

我想将 2 个四元数相乘,它们存储在cv::Mat结构中。我希望该功能尽可能高效。到目前为止,我有以下代码:

/** Quaternion multiplication
 *
 */
void multiplyQuaternion(const Mat& q1,const Mat& q2, Mat& q)
{
    // First quaternion q1 (x1 y1 z1 r1)
    const float x1=q1.at<float>(0);
    const float y1=q1.at<float>(1);
    const float z1=q1.at<float>(2);
    const float r1=q1.at<float>(3);

    // Second quaternion q2 (x2 y2 z2 r2)
    const float x2=q2.at<float>(0);
    const float y2=q2.at<float>(1);
    const float z2=q2.at<float>(2);
    const float r2=q2.at<float>(3);


    q.at<float>(0)=x1*r2 + r1*x2 + y1*z2 - z1*y2;   // x component
    q.at<float>(1)=r1*y2 - x1*z2 + y1*r2 + z1*x2;   // y component
    q.at<float>(2)=r1*z2 + x1*y2 - y1*x2 + z1*r2;   // z component
    q.at<float>(3)=r1*r2 - x1*x2 - y1*y2 - z1*z2;   // r component
}

这是 OpenCV 最快的方法吗?使用定点算术会最快吗?

4

3 回答 3

4

本教程介绍访问不同像素的不同方法。与直接像素访问相比,该Mat::at函数被发现要慢约 10%,这可能是由于在调试模式下进行了额外检查。

如果你真的不喜欢表现,你应该用文中提到的 3 种不同的方法重写你的方法,然后分析以找到最适合你情况的一种。

于 2012-05-28T15:50:54.947 回答
2

曾经有一个 ARM 矢量浮点四元数乘法,我现在找不到。我可以找到这个 SIMD 库:

Bullet 3D 游戏多物理场库

于 2012-06-08T16:09:24.433 回答
0

四元数通常用于旋转 3D 矢量,因此您可以考虑检查一个四元数是否为纯矢量(即标量或实部为零)。这可以将您的工作减少到 12 个乘法、8 个加/减和一个符号翻转。

您还可以对两个纯向量使用四元数乘法来同时计算它们的点积和叉积,因此对这种特殊情况进行测试也可能是值得的。如果两个四元数都是纯向量,则只需要进行 9 次乘法、5 次加/减和 1 次符号翻转。

于 2015-03-25T08:11:16.827 回答