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

 Bobbi Bennett12 июн. 2012 г., 05:23
Возможно, стоит установить 4X4 из перемешанных версий q2 и умножить матрицу; своего рода подражать тому, что делает код физики пули. С SSE4 у opencv -should- довольно жесткая матрица умножения.
 Jav_Rock11 июн. 2012 г., 08:14
ммм, я должен попробовать этот новый класс, спасибо
 JohnB28 мая 2012 г., 09:54
16 умножений и 12 сложений - мне кажется, что улучшений не так много. Сделайте функцию встроенной! Я надеюсь, что это "на" вызовы не являются функциональными вызовами (то есть они должны быть встроенными).
 Jav_Rock28 мая 2012 г., 10:35
Это член openCV класса Mat. Я думаю, что это самый быстрый способ получить доступ к элементу Mat, но я не уверен.opencv.willowgarage.com/documentation/cpp/…
 Christian Rau08 июн. 2012 г., 21:29
Максимально эффективно? Не используйте класс матрицы, который выполняет динамическое выделение памяти и подсчет ссылок для чего-то столь же тривиального, как в первую очередь четырехкомпонентный массив. Это идеальный вариант использования для новогоMatx класс, ссылаясь на один из ваших других вопросов.

Ответы на вопрос(3)

Решение Вопроса

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

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

 Jav_Rock28 мая 2012 г., 17:53
это выглядит красиво, я посмотрю

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

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

 28 февр. 2017 г., 19:04
Действительно, или напишите и используйте подпрограмму, которая выполняет всю операцию: `vec_rotated = q * (0, vec) * q.conj ()` в одном вызове функции, некоторые операции сохраняются по сравнению с выполнением двух полных продуктов кватерниона (второй Prod всегда имеет нулевую действительную часть). Если вам необходимо повернуть множество векторов на один и тот же кватернион, особенно если они хранятся в матрице, быстрее преобразовать кватернион в матрицу вращения 3х3 и использовать его на векторах.

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

Bullet 3D Game Мультифизическая библиотека

Ваш ответ на вопрос