我想将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最快的方法吗?使用定点算法会最快吗?
答案 0 :(得分:4)
在this教程中,介绍了访问不同像素的不同方法。发现Mat::at
函数与直接像素访问相比要慢约10%,这可能是由于在调试模式下的额外检查。
如果你真的没有表现,你应该用文本中提到的3种不同的方法重写你的方法,然后分析找到最适合你情况的方法。
答案 1 :(得分:2)
有一个ARM向量浮点四元数在那里繁殖,我现在找不到。我可以找到这个SIMD库:
答案 2 :(得分:0)
四元数通常用于旋转3D矢量,因此您可以考虑检查一个四元数是纯矢量(即标量或实部为零)。这可以将你的工作减少到12倍,8个加/减,一个符号翻转。
您还可以在两个纯矢量上使用四元数乘法来同时计算它们的点和交叉乘积,因此对这种特殊情况的测试也是值得的。如果两个四元数都是纯矢量,则只需要进行9次乘法,5次加/减和一次符号翻转。