Подтвердить что ты не робот

Эффективное умножение кватернионов С++ с использованием cv:: Mat

Я хочу умножить 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? Будет ли это быстрее с использованием арифметики с фиксированной точкой?

4b9b3361

Ответ 1

В this в учебнике рассматриваются различные способы доступа к различным пикселям. Функция Mat::at оказалась на 10% медленнее по сравнению с прямым доступом к пикселям, вероятно, из-за дополнительной проверки в режиме отладки.

Если вы действительно отработали, вы должны переписать свой метод тремя различными способами, упомянутыми в тексте, а затем профилем, чтобы найти тот, который лучше всего в вашей ситуации.

Ответ 2

Там-то был квадрантий с плавающей запятой вектор ARM, умноженный на то, что я не могу найти сейчас. Я мог бы найти эту SIMD-библиотеку:

Bullet 3D Game Multiphysics Library

Ответ 3

Кватернионы часто используются для поворота 3D-векторов, поэтому вы можете рассмотреть возможность проверки того, что один кватернион является чистым вектором (т.е. скалярная или действительная часть равна нулю). Это может сократить вашу работу до 12 умножений, 8 добавлений/вычитаний и одного знака.

Вы также можете использовать умножение кватернионов на двух чистых векторах для одновременного вычисления их точечных и кросс-продуктов, поэтому тестирование этого особого случая также может стоить того. Если оба кватерниона являются чистыми векторами, вам нужно только сделать 9 умножений, 5 добавлений/вычитаний и один знак переворота.