Найти ориентацию пиксельного пятна в аффинно преобразованном изображении относительно исходной ссылки
В части моего проекта мне нужно вычислить ориентацию патча в аффинно преобразованном изображении. Теперь моя проблема в том, что я не знаю, как найти эту вычисленную ориентацию относительно исходного не деформированного изображения.
Например, точка в искривленном изображении найдена (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]