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

Программка калибрующая камеру

Recommended Posts

Только, что посмотрел этот сайт, перед тем как зайти сюда )))

Но так и не посмотрел клип.

Здесь картинка ронравилась и по-русски все:

http://www.comprice.ru/articles/detail.php...&print=true

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


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

Здесь как искать координаты и ориентацию камер:

http://www.graphicon.ru/2006/wr22_85_Kalin...nikovaYurin.pdf

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


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

http://www.graphicon.ru/2006/wr22_85_Kalin...nikovaYurin.pdf

Не могу разобраться. Почитал еще пару статей.

На счет OpenCV пара вопросов:

FindFundamentalMat - это возвращает фун. матрицу, но там даже не надо передавать размеры изображения.

Там написано, что полученную матрицу можно использовать в двух функциях:

1) - cvComputeCorrespondEpilines(const CvMat* points, int whichImage, const CvMat* F, CvMat* lines)

points - это 2D точки. whichImage - что это определяет? lines - это эпиполярные линии?

2) - StereoRectifyUncalibrated(points1,points2,F,imageSize, CvMat* H1, CvMat* H2, double threshold=5)

Что такое H1,H2 (homography) ,threshold ?

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


Ссылка на сообщение
Поделиться на других сайтах
Не могу разобраться. Почитал еще пару статей.

На счет OpenCV пара вопросов:

FindFundamentalMat - это возвращает фун. матрицу, но там даже не надо передавать размеры изображения.

Там написано, что полученную матрицу можно использовать в двух функциях:

1) - cvComputeCorrespondEpilines(const CvMat* points, int whichImage, const CvMat* F, CvMat* lines)

points - это 2D точки. whichImage - что это определяет? lines - это эпиполярные линии?

2) - StereoRectifyUncalibrated(points1,points2,F,imageSize, CvMat* H1, CvMat* H2, double threshold=5)

Что такое H1,H2 (homography) ,threshold ?

whichImage - указывает на каком изображении заданы точки. Коэффициенты a,b,c уравнения эпиполярной линии ax + by + c = 0 для другого изображения хранятся в массиве lines. То есть задаем точку на первом изображении whichImage=1, получаем линию на втором, и наоборот.

H1,H2 - матрицы гомографии для первого и второго изображения, threshold, насколько я понял, если не равен нулю, то точки, не соответствующие эпиполярной геометрии отсеиваются по неравенству |points2T * F * points1| > threshold до выполнения функции.

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


Ссылка на сообщение
Поделиться на других сайтах
H1,H2 - матрицы гомографии для первого и второго изображения.

А что такое матрицы гомографии? Как можно их использовать?

Коэффициенты a,b,c уравнения эпиполярной линии ax + by + c = 0 для другого изображения хранятся в массиве lines. То есть задаем точку на первом изображении whichImage=1, получаем линию на втором, и наоборот.

Я не пойму одного. Если у нас есть эпиполярные линии, значит известны координаты камер?

По-моему если не известны расположения камер, эпиполярные линии нельзя найти.

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


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

Как мне вызвать cvFindFundamentalMat?

Делаю вот так:

int main( int argc, char** argv )

{

int n=8;

double pts1[]={0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0};

double pts2[]={0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0};

CvMat points_a=cvMat(n, 2, CV_32F,pts1);

CvMat points_b=cvMat(n, 2, CV_32F,pts2);

vector<uchar> status;

double pixel_tolerance = 3;

double confidence = 0.96;

CvMat fund_mat=cvMat(3, 3, CV_32F);

int out = cvFindFundamentalMat(&points_a, &points_b, &fund_mat, CV_FM_RANSAC,pixel_tolerance, confidence); // Здесь происходит ошибка.

return 0;

}

Заускается и появляется ошибка:

OpenCV Error: Internal error (Assertion: CV_IS_MAT(fmatrix) && fmatrix->cols ==

3 && (fmatrix->rows == 3 || (fmatrix->rows == 9 && method == CV_FM_7POINT)) fail

ed) in cvFindFundamentalMat, file ..\..\..\OpenCV\src\cv\cvfundam.cpp, line 600

Проблема решена))

Надо было написать так:

double elements[]={0,0,0, 0,0,0, 0,0,0};

CvMat fund_mat=cvMat(3, 3, CV_32F,elements);

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


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

void printmat(CvMat &mat)

{

	int i,j;

	for (i=0; i<mat.rows; i++)

	{

		for (j=0; j<mat.cols; j++)

		{

			printf("%.3f ",cvmGet(&mat,i,j));

		}

		printf("\n");

	}

}


int main( int argc, char** argv )

{

	int n=8;

	double pts1[]={126,120, 331,116, 153,217, 192,236, 69,245, 301,216, 215,273, 270,280};


	double pts2[]={337,61, 394,78, 264,155, 502,174, 336,158, 311,184, 195,212, 408,240};


	CvMat points_a=cvMat(n, 2, CV_32F,pts1);

	CvMat points_b=cvMat(n, 2, CV_32F,pts2);

	for (int i=0; i<8; i++)

	{

		cvmSet(&points_a,i,0,pts1[i*2]);

		cvmSet(&points_a,i,1,pts1[i*2+1]);

	}

	for (int i=0; i<8; i++)

	{

		cvmSet(&points_b,i,0,pts2[i*2]);

		cvmSet(&points_b,i,1,pts2[i*2+1]);

	}

	vector<uchar> status; 

	double pixel_tolerance = 3; 

	double confidence = 0.96; 

	double mt[]={0,0,0, 0,0,0, 0,0,0};

	CvMat fund_mat=cvMat(3, 3, CV_32F,mt);

	int out = cvFindFundamentalMat(&points_a, &points_b, &fund_mat, CV_FM_RANSAC,pixel_tolerance, confidence); 

	double lines_[]={0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0};

	CvMat lines1=cvMat(n, 3, CV_32F,lines_);

	CvMat lines2=cvMat(n, 3, CV_32F,lines_);

	cvComputeCorrespondEpilines(&points_a,1,&fund_mat,&lines1);

	cvComputeCorrespondEpilines(&points_b,2,&fund_mat,&lines2);

	printf("\nlines1:\n");

	printmat(lines1);

	printf("\nlines2:\n");

	printmat(lines2);

	getch();

	return 0;

}

После выполнения кода fund_mat выглядит так:

0.000 0.000 -0.002

-0.000 0.000 0.007

0.001 -0.010 1.000

lines1:

0.042 -0.999 114.858

0.017 -1.000 127.623

-0.238 -0.971 253.277

-0.292 -0.956 278.934

-0.242 -0.970 255.143

-0.332 -0.943 297.160

-0.417 -0.909 335.667

-0.551 -0.835 393.708

lines2:

0.042 -0.999 114.858

0.017 -1.000 127.623

-0.238 -0.971 253.277

-0.292 -0.956 278.934

-0.242 -0.970 255.143

-0.332 -0.943 297.160

-0.417 -0.909 335.667

-0.551 -0.835 393.708

Думаю это не правильно. Где я ошибся?

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


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

double lines_[]={0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0};

CvMat lines1=cvMat(n, 3, CV_32F,lines_);

CvMat lines2=cvMat(n, 3, CV_32F,lines_);

Все законно, указана одна и та же память lines_. Сделайте lines_1 и lines_2.

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


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

Спасибо!! Вроде получилось, НО не правильно.

Как мне задавать координаты точек? Там даже не передаются размеры изображения.

Где находится начало координат?

Вот скрин как получилось :

post-1202-1283087301_thumb.jpg

post-1202-1283087709_thumb.jpg

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


Ссылка на сообщение
Поделиться на других сайтах
Спасибо!! Вроде получилось, НО не правильно.

Как мне задавать координаты точек? Там даже не передаются размеры изображения.

Где находится начало координат?

Вот скрин как получилось :

Да нет :( просто линии с первого и второго изображения перепутаны ;)

(хотя, посмотрел получше вроде и если поменять тоже не сходятся)

Там важны координаты точек измеренных в системе координат камер (кадра).

Размеры изображения значения не имеют.

И ориентацию получаем как относительное угловое и линейное смещение одной системы координат относительно другой.

А можете показать, кусок кода, который линии строит?

ЗЫ: картинки в футуристическом стиле.

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


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

Написал на Delphi, чтобы не заморачиватся на C++.

<code class='no-highlight'>function getY(x:Integer; a,b,c:Double):Integer;

Begin

  //уравнение прямой ax+by+c=0, подставляю X, и получаю Y.

  result:=Round((-a*x-c)/B);

end;


procedure DrawLines;

//Линии которые возвращает cvComputeCorrespondEpilines

const arr:Array [0..7,0..2] of Double=((-0.132,0.991,-15.688),(-0.166,0.986,27.682),

(-0.031,1.000,-141.481),(-0.005,1.000,-173.332),(-0.025,1.000,-149.178),

(0.013,1.000,-195.933),(0.033,0.999,-220.192), (0.062,0.998,-255.926));


//точки на изображении

const pts:Array [0..7,0..1] of double =(

	(337,61), (394,78),(264,155),(502,174),

	(336,158),(311,184),(195,212),(408,240));


var i,j:Integer;

begin

  image1.Canvas.Pen.Color:=clRed;

  for j:=0 to 7 do

  Begin

	image1.Canvas.Ellipse(Round(pts[j][0]-3),Round(pts[j][1])-3,Round(pts[j][0])+3,Round(pts[j][1])+3);//Здесь рисуем точки

	for i:=1 to 100 do

	Begin

	  image1.Canvas.MoveTo((i-1)*10, getY((i-1)*10, arr[j][0], arr[j][1], arr[j][2]));

	  image1.Canvas.LineTo(i*10, getY(i*10, arr[j][0], arr[j][1], arr[j][2]));

	end;

  end;

end;

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


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

Ну вот я подставляю:

-0.132*337+0.991*61-15.688=близко к нулю, отсюда следует, что точка (337,61) лежит на линии (-0.132,0.991,-15.688).

Так что все правильно считает, строит не правильно что-то.

ЗЫ: Прямую можно строить по 2-м точкам, а не по 100 (200).

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


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

Да я знаю.

Некоторые точки рисует правильно, например 1 точка.

Если нарисовать вторую линию : -0.166,0.986,27.682 , (394,78)

Y=(0.166*394-27.682)/0.986;

Y равно 38.25, а не 78 !

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


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

Некоторые точки рисует правильно, например 1 точка.

Если нарисовать вторую линию : -0.166,0.986,27.682 , (394,78)

Y=(0.166*394-27.682)/0.986;

Y равно 38.25, а не 78 !

Есть еще одно предположение:

CV_32F это не double а float, из за этого может выводиться ерунда.

Я про эти строчки:

double pts1[]={126,120, 331,116, 153,217, 192,236, 69,245, 301,216, 215,273, 270,280};

double pts2[]={337,61, 394,78, 264,155, 502,174, 336,158, 311,184, 195,212, 408,240};

CvMat points_a=cvMat(n, 2, CV_32F,pts1);

CvMat points_b=cvMat(n, 2, CV_32F,pts2);

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


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

Получилось, Спасибо!

Я расставил камеры по прямым углом, Эпиполярные линии рисует точно !

Наверное в первый раз не получилось из-за не правильного расположения камер, надо проверить по разным положениям камер (Вечером сделаю).

Если есть эпиполярные линии и эпиполярные точки, как мне найти координаты камер? Может это тоже OpenCV сможет сделать?

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


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

Я расставил камеры по прямым углом, Эпиполярные линии рисует точно !

Наверное в первый раз не получилось из-за не правильного расположения камер, надо проверить по разным положениям камер (Вечером сделаю).

Если есть эпиполярные линии и эпиполярные точки, как мне найти координаты камер? Может это тоже OpenCV сможет сделать?

Вроде как матрица гомографии определяет положение одной камеры относительно другой.

Еще ссылки:

http://www.nada.kth.se/~danik/VSpapers/MalisSlides1.pdf

http://www.google.ru/url?sa=t&source=w...srQ&cad=rjt

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


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

Спасибо за ссылки! Вот бы с самого начала они у меня были.

Скоро пойму как работают матрицы хомографии, потом можно будет править миром :D

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


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

С эпиполярными линиями все понятно, все работает почти при любых позициях камер.

Но все-же не могу найти координаты камер :D

Пробовал по разному:

cvFindHomography вроде что-то возвращает, но не знаю как использовать дальше.

int out=cvStereoRectifyUncalibrated(&points_1,&points_2,&fund_mat,cvSize(640,480),&H1,&H2);

Здесь H1 полностью равен H2. out=1;

Извините что надоедаю, но КАК МНЕ НАЙТИ КООРДИНАТЫ КАМЕР?

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


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

Извините, но я только сейчас увидел ваше сообщение, с файлом.

Сейчас не могу посмотреть, только вечером.

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


Ссылка на сообщение
Поделиться на других сайтах
Извините, но я только сейчас увидел ваше сообщение, с файлом.

Сейчас не могу посмотреть, только вечером.

В этой презентации на 32 стр показано, как соотносится матрица гомографии с поворотом и фокусным расстоянием камер.

http://www.google.ru/url?sa=t&source=w...eeeS5UhsrMRNBWQ

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


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

Всем ПРивет!!!!

Интересует такой вопрос.. Знаю что в ОпенСВ есть методы калибровки камеры, так вот, пробывал компилировать програмку которая шла как пример в книге Learning OpenCV,(Gary Bradski and Adrian Kaehler) все работает, все выравнивает.. изучив даный метод и даные характеристики выкривлений то понял что програма заточена под так званые "Barrel distortion" (бочковые искажения) http://en.wikipedia.org/wiki/Distortion_%28optics%29, так вот проблема в том что фотографии которые я делаю, имеющимся у меня фотоапаратом, имеют другой тип искажений "Pincushion distortion", и в результате получается полный бред (после кореляции, фотографии искажаются еще хуже). Не могу понять, есть ли метод в ОпенСВ который применяется к другим типам искажений????? Или я в чем-то не прав???

Заранее благодарен!!!!!

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


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

Насколько я понял, Pincushion distortion - это "вогнутость" изображения, вот тут вроде такое исправляют:

http://dsynflo.blogspot.com/2010/03/camera-calibration-using-opencv.html

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


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

Насколько я понял, Pincushion distortion - это "вогнутость" изображения, вот тут вроде такое исправляют:

http://dsynflo.blogspot.com/2010/03/camera-calibration-using-opencv.html

Спасибо за ресурс...Буду разбераться!!!!

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


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

)))))) Посмотрел данную сылку,... у них тот-же пример с книги)))))

Буду наверное експереминтировать с линзамы что-бы понять физику искажений......и че-куда искажает!!!!

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×