Найти ориентацию пиксельного пятна в аффинно преобразованном изображении относительно исходной ссылки

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

Например, точка в искривленном изображении найдена (100,200). Я могу извлечь ориентацию этой точки, используя 8x8 соседних пикселей. Предположим, что это 30 градусов. деформированное изображение, в котором найдена точка, является результатом применения преобразования к исходному изображению с углом 60 градусов по каждой оси (шаг, рыскание и поворот). (Это извлечение ориентации обычно известно как извлечение дескриптора в компьютерном зрении)

Теперь матрица преобразования известна. ориентация точки в преобразованном изображении также известна. Положение точки относительно ссылки известно (используется обратное преобразование). Теперь я хочу знать, какова новая ориентация, если эта точка (100 200) переходит в систему отсчета (например, 150 250). другими словами, какова новая ориентация по отношению к эталонному изображению.

Я знаю, что это просто, чтобы решить, если у нас есть только угол поворота крена (60 градусов). в этом случае ориентация относительно системы отсчета будет 30+60 = 90 .

Я попытался реализовать это с помощью OpenCV:

        cv::Mat rvec1(3,1,CV_32F); // rot vector related to B
        rvec1.at<float>(0,0)=0;
        rvec1.at<float>(1,0)=30*to_RAD;
        rvec1.at<float>(2,0)=0;

        cv::Mat rvec2(3,1,CV_32F); // rot vector related to A
        rvec2.at<float>(0,0)=0;
        rvec2.at<float>(1,0)=60*to_RAD;
        rvec2.at<float>(2,0)=0;

        cv::Mat R_A;
        cv::Mat R_B;

        cv::Rodrigues(rvec1, R_B);
        cv::Rodrigues(rvec2, R_A);

        cv::Mat R_combined= R_B*R_A;

        cv::Mat rvec_result;
        cv::Rodrigues(R_combined,rvec_result);

Я хочу создать вращение Mat A и B, используя 2 вектора вращения. и после умножения этих двух я хочу преобразовать его в вектор вращения. Но единственное, что я получаю, это ошибка времени выполнения в последней строке (cv::Rodrigues(R_combined,rvec_result);)

Спасибо за вашу помощь заранее.

1 ответ

Решение

Хорошо, звучит так, как будто у вас есть две матрицы вращения (вы можете использовать родриги для их получения), назовите их A и B. Вы хотите знать, как их объединить. Допустим, A обозначает ориентацию вашей стрелки относительно патча, а B обозначает патч относительно источника. Давайте начнем с нашего происхождения в центре патча. А описывает ориентацию стрелки. Теперь мы хотим повернуть начало координат на B, чтобы наша исходная ось отсчета теперь находилась в точке B относительно нового источника. Чтобы сделать это просто сделать

Combined = [B]*[A];

Обновить

Я не знаю, почему ваш код выдаст вам ошибку, он отлично работает для меня. Вот код, который я запустил.

cv::Mat rvec1(3,1,CV_32F); // rot vector related to B
rvec1.at<float>(0,0)=0;
rvec1.at<float>(1,0)=30*M_PI/180;;
rvec1.at<float>(2,0)=0;

cv::Mat rvec2(3,1,CV_32F); // rot vector related to A
rvec2.at<float>(0,0)=0;
rvec2.at<float>(1,0)=60*M_PI/180;;
rvec2.at<float>(2,0)=0;

cv::Mat R_A;
cv::Mat R_B;

cv::Rodrigues(rvec1, R_B);
cv::Rodrigues(rvec2, R_A);

cv::Mat R_combined= R_B*R_A;

cv::Mat rvec_result;
cv::Rodrigues(R_combined,rvec_result);

std::cout << rvec1 << std::endl<<std::endl;
std::cout << rvec2 << std::endl<<std::endl;
std::cout << R_A << std::endl<<std::endl;
std::cout << R_B << std::endl<<std::endl;
std::cout << R_combined << std::endl<<std::endl;
std::cout << rvec_result << std::endl<<std::endl;

И вот мой вывод

[0; 0.52359879; 0]

[0; 1.0471976; 0]

[0.49999997, 0, 0.86602545;
0, 1, 0;
-0.86602545, 0, 0.49999997]

[0.86602539, 0, 0.5;
0, 1, 0;
-0.5, 0, 0.86602539]

[-5.9604645e-08, 0, 1;
0, 1, 0;
-1, 0, -5.9604645e-08]

[0; 1.5707964; 0]
Другие вопросы по тегам