Перейти к содержимому
Compvision.ru
mrgloom

Дисторсии(подушка,бочка)

Recommended Posts

собственно вопрос как реализовать дисторсии(подушка, бочка) на OpenCV?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

cvInitUndistortMap + cvRemap

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

в книге орелли 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

  );

а как заполнить эти структуры ,если я хочу сжимать\разжимать подушку бочку по вертикали\горизонтали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно через cvInitUndistortMap заполнить mapx и mapy, а затем заполнить mapx или mapy значениями равными значениям номера столбца (для mapx) или номера строки (для mapy), тем самым, устранив коррекцию по одной из осей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Можно через cvInitUndistortMap заполнить mapx и mapy

это я понял и так, я не понял чем заполнять intrinsic и distortion. первое это какая то матрица 3х3, а второе какие то параметры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вот здесь есть про эти матрицы: http://courses.graphicon.ru/files/courses/vision/2006/lectures/lect07_06.ppt

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

как то не очень осилил документ

но нашел

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

оригинал

distorted.gif

как должно быть

undistorted.gif

и как у меня получается сейчас.

image.png

вообщем непонятно как расширить изображение когда преобразование подушка(или обрезать только нужный прямоугольник при преобразовании бочка)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В этом топике: http://www.compvision.ru/forum/index.php?showtopic=423 выкладывал проект по стерео-зрению, перед 3d реконструкцией производится ректификация изображений с помощью cvInitUndistortMap + cvRemap

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ну так там опять же калибровка по доске наверно, как пользоваться cvInitUndistortMap + cvRemap я уже понял, даже понятно как задается матрица intrinsic_matrix (по русски собственная матрица?)

image.png

а вот какой математический смысл в distortion_coeffs я не понял, только поиграл значениями посмотрел как изменяется.

и так же непонятно как после преобразования бочка (после того как изображение уменьшится) вычислить вписанный в него прямоугольник и по нему обрезать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

еще подкину

http://opencv.willowgarage.com/documentation/STRAWMAN/cpp/camera_calibration_and_3d_reconstruction.html

вроде бы можно координаты углов вычислить по этим формулам

054f0abbb6938203d15f91dd5f8e3b1bd19c1666.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

после коррекции я получаю

image.png

и мне надо как то выделить квадрат помеченный красным, и сделать ресайз этого квадрата на всё изображение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А может посмотреть что в угловых точках матрицы ремапа mapx и mapy содержится? Там должны быть координаты угловых точек этой подушки. Затем назначить ROI скопировать оттуда квадратный кусок, после этого Resize. Я так думаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

на начальном этапе (не преобразованное изображение) показывает ровно те же координаты углов (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);

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Похоже что координаты углов (первого и четвертого):

(-cx1;-cy1)

(w-cx4;h-cy4)

, где h,w - ширина и высота результирующего изображения(из которого надо вырезать кусок).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

похоже вы правы

а то я начал уже вот так извращатся

//для случая если изображение не квардратное

// для точки (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;

		}

	}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Похоже что координаты углов (первого и четвертого):

(-cx1;-cy1)

(w-cx4;h-cy4)

, где h,w - ширина и высота результирующего изображения(из которого надо вырезать кусок).

только

(2*w-cx4;2*h-cy4)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

хотя нет, проверил, не работает.

но дает похожие результаты при малом отклонении.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

хотя нет, проверил, не работает.

но дает похожие результаты при малом отклонении.

Я был не прав, там формула такая: dst(x,y)=src(mapx(x,y),mapy(x,y))

значит в массиве mapx и maxy надо искать значения, наиболее близкие к координатам углов исходного изображения.

Тогда мы узнаем куда они "съехали".

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Я был не прав, там формула такая: dst(x,y)=src(mapx(x,y),mapy(x,y))

значит в массиве mapx и maxy надо искать значения, наиболее близкие к координатам углов исходного изображения.

Тогда мы узнаем куда они "съехали".

ну я так и делаю, иду по линии которая соединяет левый верхний угол и центр и ищу когда cvGetReal2D возвратит положительное значение, потом из этой точки и зная, что центр отображается в центр (0,0)->(0,0) нахожу все остальные точки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Реализовал метод устранения дисторсии изображения по статье "Camera Calibration with Lens Distortion from Low-rank Textures":

post-1-0-38117900-1365844210_thumb.png

(это не готовая утилита, а демонстрация метода)

SelfCalibration.cpp

Изображение из примера:

post-1-0-57728200-1365844637_thumb.jpg

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×