Основная математика
Предполагается, что у вас есть 2 2D изображения, и вы хотите найти вращение между ними. Например, первое изображение - передняя параллель 0 градусов. Тогда второй - это угол, который вы хотите найти.
Пожалуйста, ознакомьтесь с некоторыми основами здесь https://www.ifi.uzh.ch/dam/jcr:5759a719-55db-4930-8051-4cc534f812b1/VO_Part_I_Scaramuzza.pdf
![enter image description here](https://i.stack.imgur.com/PZujf.png)
Это захват двухмерного и двумерного движения из соответствия функции изображения. Здесь слишком много математики. Я не пойду, хотя все. По сути, вы ищете необходимую матрицу, которая имеет ранг 2 и содержит все векторы вращения и перемещения
![enter image description here](https://i.stack.imgur.com/UCjEF.png)
Минимальное решение для случая включает пять 2-D-2-D соответствий, как описано в
E. Kruppa, «Zur ermittlung eines objektes aus zwei perspektiven mit
Innerrer Ориентир, ”Sitzungsberichte der Akademie der Wissenschaften,
Вена, Mathematisch-Naturwissenschaftlichen Klasse, Abteilung IIa,
том 122, стр. 1939–1948, 1913.
Более популярным методом является восьмиточечный алгоритм Лонге-Хиггинса. более 8 соответствующих совпадающих точек.
Просто укажите точку соответствия, как показано ниже
![enter image description here](https://i.stack.imgur.com/wfnKk.png)
Поскольку вы можете откалибровать камеру перед ручкой, F можно заменить на E напрямую.
Также вы должны пройти эпиполярную геометрию в книге по геометрии Multiview, как видно из рисунка выше
Если ваша камера RGBD, вам нужно только 3 точки для сопоставления, это называется 3D-3D оценкой движения в первой ссылке.
Кодировка
Предположим, вы знаете всю базовую математику. Установите opencv соответственно
Предположим, что вы использовали изображение в img1 и img2. img 1 - передняя параллель. а изображение 2 - это угол поворота, который вы хотите найти.
Mat img_1_c = imread(filename1);
Mat img_2_c = imread(filename2); //each file should not have any color drawing inside
Вы можете вручную редактировать совпадающие точки, например, 4 угла с центральной точкой
vector<Point2f> points1, points2; //each topic have at least 5 point inside
Самый простой способ - использовать маршрутизацию обнаружения функций в OpenCV (необязательно)
cvtColor(img_1_c, img_1, COLOR_BGR2GRAY);
cvtColor(img_2_c, img_2, COLOR_BGR2GRAY);
featureDetection(img_1, points1); //detect features in img_1
vector<uchar> status;
featureTracking(img_1,img_2,points1,points2, status); //track those features to img_2
если базовое движение слишком велико, вы можете пойти по пути сопоставления дескриптора детектора. (необязательно)
SurfFeatureDetector detector(400);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img_1, keypoints1);
detector.detect(img_2, keypoints2);
// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img_1, keypoints1, descriptors1);
extractor.compute(img_2, keypoints2, descriptors2);
// matching descriptors
BFMatcher matcher(NORM_L2);
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img_1, keypoints1, img_2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
Введите фокальную и принципиальную точку камеры из внутренней калибровки камеры https://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html
double focal = XXXX;
cv::Point2d pp(XXXXX, XXxxx); // this should be around the center of image if it is too far away, check you calibration process
Mat E, R, t, mask;
E = findEssentialMat(points2, points1, focal, pp, RANSAC, 0.999, 1.0, mask);
recoverPose(E, points2, points1, R, t, focal, pp, mask);
R и t содержат вращение и перевод (не в реальном масштабе).
Mat Euler_vec;
Rodrigues(R,Euler_vec);
cout<<Euler_vec<<endl;
Тогда Euler_vec должен содержать нужный вам угол. Значение, которое вы ищете, должно быть в первом или последнем столбце