Jump to content
Compvision.ru
Smorodov

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

Recommended Posts

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

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

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

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

Share this post


Link to post
Share on other sites
Здесь как искать координаты и ориентацию камер:

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 ?

Share this post


Link to post
Share on other sites
Не могу разобраться. Почитал еще пару статей.

На счет 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 до выполнения функции.

Share this post


Link to post
Share on other sites
H1,H2 - матрицы гомографии для первого и второго изображения.

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

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

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

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

Share this post


Link to post
Share on other sites

Как мне вызвать 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);

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

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

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

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

post-1202-1283087301_thumb.jpg

post-1202-1283087709_thumb.jpg

Share this post


Link to post
Share on other sites
Спасибо!! Вроде получилось, НО не правильно.

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

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

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

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

Написал на 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;

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

Да я знаю.

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

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

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

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

Share this post


Link to post
Share on other sites
Да я знаю.

Некоторые точки рисует правильно, например 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);

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites
Получилось, Спасибо!

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

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

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

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

Еще ссылки:

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
Извините, но я только сейчас увидел ваше сообщение, с файлом.

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

×