mrgloom 242 Жалоба Опубликовано March 24, 2011 собственно вопрос как реализовать дисторсии(подушка, бочка) на OpenCV? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано March 24, 2011 cvInitUndistortMap + cvRemap 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 15, 2011 в книге орелли cvInitUndistortMap заполняется через калибровку по доске. т.е. intrinsic,distortion получают из cvCalibrateCamera2. CvMat* intrinsic_matrix = cvCreateMat(3,3,CV_32FC1); CvMat* distortion_coeffs = cvCreateMat(5,1,CV_32FC1); IplImage* mapx = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, 1 ); IplImage* mapy = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, 1 ); cvInitUndistortMap( intrinsic, distortion, mapx, mapy ); а как заполнить эти структуры ,если я хочу сжимать\разжимать подушку бочку по вертикали\горизонтали? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 15, 2011 Можно через cvInitUndistortMap заполнить mapx и mapy, а затем заполнить mapx или mapy значениями равными значениям номера столбца (для mapx) или номера строки (для mapy), тем самым, устранив коррекцию по одной из осей. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 15, 2011 Можно через cvInitUndistortMap заполнить mapx и mapy это я понял и так, я не понял чем заполнять intrinsic и distortion. первое это какая то матрица 3х3, а второе какие то параметры. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 15, 2011 Вот здесь есть про эти матрицы: http://courses.graphicon.ru/files/courses/vision/2006/lectures/lect07_06.ppt Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 15, 2011 как то не очень осилил документ но нашел float camIntrinsics[] = { focalX, 0, centerX, 0, focalY, centerY, 0, 0, 1 }; float distortionCoeffs[] = { radialDistX, radialDistY, tangentDistX, tangentDistY }; вообщем буду пробовать методом тыка. и про 5 параметров x' = x + x*(K1*r^2 + K2*r^4 + K3*r^6) + P1*(r^2 + 2*x^2) + 2*P2*x*y y' = y + y*(K1*r^2 + K2*r^4 + K3*r^6) + P2*(r^2 + 2*y^2) + 2*P1*x*y Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 15, 2011 оригинал как должно быть и как у меня получается сейчас. вообщем непонятно как расширить изображение когда преобразование подушка(или обрезать только нужный прямоугольник при преобразовании бочка) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
RinOS 16 Жалоба Опубликовано April 15, 2011 В этом топике: http://www.compvision.ru/forum/index.php?showtopic=423 выкладывал проект по стерео-зрению, перед 3d реконструкцией производится ректификация изображений с помощью cvInitUndistortMap + cvRemap Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 15, 2011 ну так там опять же калибровка по доске наверно, как пользоваться cvInitUndistortMap + cvRemap я уже понял, даже понятно как задается матрица intrinsic_matrix (по русски собственная матрица?) а вот какой математический смысл в distortion_coeffs я не понял, только поиграл значениями посмотрел как изменяется. и так же непонятно как после преобразования бочка (после того как изображение уменьшится) вычислить вписанный в него прямоугольник и по нему обрезать. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 15, 2011 еще подкину http://opencv.willowgarage.com/documentation/STRAWMAN/cpp/camera_calibration_and_3d_reconstruction.html вроде бы можно координаты углов вычислить по этим формулам Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 19, 2011 после коррекции я получаю и мне надо как то выделить квадрат помеченный красным, и сделать ресайз этого квадрата на всё изображение. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 19, 2011 А может посмотреть что в угловых точках матрицы ремапа mapx и mapy содержится? Там должны быть координаты угловых точек этой подушки. Затем назначить ROI скопировать оттуда квадратный кусок, после этого Resize. Я так думаю. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 20, 2011 на начальном этапе (не преобразованное изображение) показывает ровно те же координаты углов (0,0) (w,0) (0,h) (w,h) как начинаю сжимать (в бочку) то выдает там где были 0 отрицательные значения, там где были w,h больше их. как это интерпретировать? использую код: int h= img->height; int w= img->width; int cx1= cvGetReal2D(mapx, 0, 0); int cy1= cvGetReal2D(mapy, 0, 0); int cx2= cvGetReal2D(mapx, w-1, 0); int cy2= cvGetReal2D(mapy, w-1, 0); int cx3= cvGetReal2D(mapx, 0, h-1); int cy3= cvGetReal2D(mapy, 0, h-1); int cx4= cvGetReal2D(mapx, w-1, h-1); int cy4= cvGetReal2D(mapy, w-1, h-1); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 20, 2011 Похоже что координаты углов (первого и четвертого): (-cx1;-cy1) (w-cx4;h-cy4) , где h,w - ширина и высота результирующего изображения(из которого надо вырезать кусок). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 20, 2011 похоже вы правы а то я начал уже вот так извращатся //для случая если изображение не квардратное // для точки (0,0) int px0=0; int py0=0; double Scy= (double)h/w; for(int x=0;x<w/2;x++) { double y= Scy*x; int t= cvGetReal2D(mapx, floor(y), x); if (t>=0) { px0=x; py0=y; break; } } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 20, 2011 Похоже что координаты углов (первого и четвертого): (-cx1;-cy1) (w-cx4;h-cy4) , где h,w - ширина и высота результирующего изображения(из которого надо вырезать кусок). только (2*w-cx4;2*h-cy4) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 20, 2011 хотя нет, проверил, не работает. но дает похожие результаты при малом отклонении. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 20, 2011 хотя нет, проверил, не работает. но дает похожие результаты при малом отклонении. Я был не прав, там формула такая: dst(x,y)=src(mapx(x,y),mapy(x,y)) значит в массиве mapx и maxy надо искать значения, наиболее близкие к координатам углов исходного изображения. Тогда мы узнаем куда они "съехали". Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано April 20, 2011 Я был не прав, там формула такая: dst(x,y)=src(mapx(x,y),mapy(x,y)) значит в массиве mapx и maxy надо искать значения, наиболее близкие к координатам углов исходного изображения. Тогда мы узнаем куда они "съехали". ну я так и делаю, иду по линии которая соединяет левый верхний угол и центр и ищу когда cvGetReal2D возвратит положительное значение, потом из этой точки и зная, что центр отображается в центр (0,0)->(0,0) нахожу все остальные точки. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 13, 2013 Реализовал метод устранения дисторсии изображения по статье "Camera Calibration with Lens Distortion from Low-rank Textures": (это не готовая утилита, а демонстрация метода) SelfCalibration.cpp Изображение из примера: 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах