Я пытаюсь найти евклидово преобразования между двумя камерами (или на самом деле, одна двигающейся камерой), захватив ту же сцену, где данные калибровок K (внутренний PARAMS) и d (коэффициенты искажения). Я делаю это путем извлечения точек отличия, сопоставления их и использования лучших совпадений в качестве соответствий.undistort против undistortPoints для сопоставления характеристик калиброванных изображений
Перед изменением размера/обнаружением признаков/и т.д. Я undistort
оба изображения
undistort(img_1, img_1_undist, K, d);
undistort(img_2, img_2_undist, K, d);
, где img_.
являются входами в Mat
форме, полученные imread
. Но на самом деле мне нужны только неискаженные координаты функций, которые я в конечном итоге использую в качестве соответствий, а не для всех пикселей изображения, поэтому было бы более эффективным, а не undistort
всего изображения, а только ключевые точки. Я думал, что смогу сделать это с помощью undistortPoints
, однако оба подхода приведут к разным результатам.
изменить размер изображения
resize(img_1_undist, img_1_undist, Size(img_1_undist.cols/resize_factor,
img_1_undist.rows/args.resize_factor));
resize(img_2_undist, img_2_undist, Size(img_2_undist.cols/resize_factor,
img_2_undist.rows/args.resize_factor));
// scale matrix down according to changed resolution
camera_matrix = camera_matrix/resize_factor;
camera_matrix.at<double>(2,2) = 1;
После получения лучших матчей в matches
я строю std::vector
с для координат указанных матчей,
// Convert correspondences to vectors
vector<Point2f>imgpts1,imgpts2;
cout << "Number of matches " << matches.size() << endl;
for(unsigned int i = 0; i < matches.size(); i++)
{
imgpts1.push_back(KeyPoints_1[matches[i].queryIdx].pt);
imgpts2.push_back(KeyPoints_2[matches[i].trainIdx].pt);
}
который я затем использовать для нахождения существенной матрицы.
Mat mask; // inlier mask
vector<Point2f> imgpts1_undist, imgpts2_undist;
imgpts1_undist = imgpts1;
imgpts2_undist = imgpts2;
/* undistortPoints(imgpts1, imgpts1_undist, camera_matrix, dist_coefficients,Mat(),camera_matrix); // this doesn't work */
/* undistortPoints(imgpts2, imgpts2_undist, camera_matrix, dist_coefficients,Mat(),camera_matrix); */
Mat E = findEssentialMat(imgpts1_undist, imgpts2_undist, 1, Point2d(0,0), RANSAC, 0.999, 8, mask);
Когда я удалить вызовы undistort
и вместо того, чтобы позвонить undistortPoints
на ключевые точки, она не производит тот же результат (который я бы ожидать). Различия иногда незначительны, но всегда там.
Я прочитал в документации по
Функция аналогична сортом :: undistort и резюме :: initUndistortRectifyMap, но она работает на разреженное множестве точек вместо растрового изображения.
такой, что функция должна делать то, что я ожидаю. Что я делаю неправильно?
* найти исходную точку с искаженной * - Как эта проблема отличается от того, что 'undistort' должно делать со всеми точками изображения? – oarfish
Когда вы искажаете изображение, вы итеративно делаете это: «Я нахожусь в позиции пикселя (i, j) неискаженного изображения: на каком пикселе (i_d, j_d) искаженного изображения мне нужно выбрать цвет, который мне нужно заполнить (ij)? Ответ (i_d, j_d) = distortion_function (i, j) «Как писал Дима, это легко вычислить: пару полиномиальных оценок. Чтобы не исказить точку (i_d, j_d) для восстановления (i, j), вместо этого вам необходимо оценить обратное значение функции distortion_function, что включает в себя решение уравнения многочлена. –
@oarfish, я отредактировал ответ, чтобы уточнить. – Dima