ОБНОВЛЕНИЕ СТАТУСА ПРАКТИКИ:
Я обнаружил, как отображать линейную линзу, от destination
координат до source
координат.
Как рассчитать радиальное расстояние от центра, чтобы перейти от "рыбий глаз" к прямолинейному?
1). Я на самом деле изо всех сил пытаюсь изменить это и сопоставить исходные координаты с координатами назначения. Что такое обратное, в коде в стиле функций преобразования, которые я разместил?
2). Я также вижу, что у меня неисторженность неидеальна на некоторых объективах — предположительно на тех, которые не являются строго линейными. Каковы эквивалентные координаты источника и места назначения для этих объективов? Опять же, больше кода, чем просто математические формулы...
Вопрос в первоначальной форме:
У меня есть несколько точек, описывающих положение на снимке, сделанном с помощью объектива «рыбий глаз».
Я хочу преобразовать эти точки в прямолинейные координаты. Я хочу не искажать изображение.
Я нашел это описание того, как создать эффект "рыбий глаз", но не то, как его обратить.
Также есть сообщение в блоге, в котором описывается, как использовать инструменты для этого; эти картинки оттуда:
(1) : SOURCE
Ссылка на исходное фото
< img src="https://i.stack.imgur.com/qLNQV.jpg" width="500" height="334" />
Входные данные: Исходное изображение с искажением "рыбий глаз", которое нужно исправить. эм>
(2) : DESTINATION
Ссылка на исходное фото
< img src="https://i.stack.imgur.com/ogb9b.jpg" width="500" height="237" />
Вывод: Исправленное изображение (технически также с коррекцией перспективы, но это отдельный шаг).
Как рассчитать радиальное расстояние от центра, чтобы перейти от «рыбий глаз» к прямолинейному?
Моя заглушка функции выглядит так:
Point correct_fisheye(const Point& p,const Size& img) {
// to polar
const Point centre = {img.width/2,img.height/2};
const Point rel = {p.x-centre.x,p.y-centre.y};
const double theta = atan2(rel.y,rel.x);
double R = sqrt((rel.x*rel.x)+(rel.y*rel.y));
// fisheye undistortion in here please
//... change R ...
// back to rectangular
const Point ret = Point(centre.x+R*cos(theta),centre.y+R*sin(theta));
fprintf(stderr,"(%d,%d) in (%d,%d) = %f,%f = (%d,%d)\n",p.x,p.y,img.width,img.height,theta,R,ret.x,ret.y);
return ret;
}
В качестве альтернативы я мог бы каким-то образом преобразовать изображение из «рыбьего глаза» в прямолинейное, прежде чем находить точки, но я совершенно сбит с толку Документация OpenCV. Есть ли простой способ сделать это в OpenCV, и достаточно ли хорошо он работает, чтобы делать это в прямом эфире?