himik
Пользователи-
Количество публикаций
13 -
Зарегистрирован
-
Посещение
-
Days Won
1
himik last won the day on February 5 2012
himik had the most liked content!
Репутация
2 НовичекО himik
-
Звание
Бывалый
-
Не пойму, как правильно калибровать камеры каждый раз пли калибровании получаются разные результаты. Расстояния всегда получаются разными, лучшее чего удалось достигнуть это погрешность 6см при чем с внесением поправок.
-
Большое сапасибо. Делаю вот так: float *ptr = (float*) (_3dImage->imageData + 240*_3dImage->widthStep); r =- ptr[3*320]; printf(" %f\n", r-1); Как я понимаю это середина изображения. После нескольких калибровок получились приемлемые значения, но есть несколько непонятных для меня фактов 1) Значение получается отрицательным приходится исправлять 2) Значение на 1 больше действительного то есть если расстояние до объекта 60 см то он покажет 160см, поэтому printf(" %f\n", r-1) 3) Значения выводятся в метрах хотя при калибровке размер квадрата шахматной доски вводился в см, то есть если расстояние до объекта 60см пишет 0.6000
-
То есть что бы узнать Z нужно у точки на изображении (x,y) узнать параметры B, G, R ну вернее только R. Но как это сделать?
-
Честно говоря не понял из того что вы написали почти нечего можете подсказать в каком из пунктов какие функции использовать. Вот нашел тут на все том же http://blog.martinperis.com вот такой код: d = pointRightImage.X - pointLeftImage.X; X = pointLeftImage.X * Q[0, 0] + Q[0, 3]; Y = pointLeftImage.Y * Q[1, 1] + Q[1, 3]; Z = Q[2, 3]; W = d * Q[3, 2] + Q[3, 3]; X = X / W; Y = Y / W; Z = Z / W;
-
Ну так я сначала создаю изображение: IplImage *_3dImage=cvCreateImage( cvSize(imageLeft->width,imageLeft->height), 32, 3); Затем уже делаю cvReprojectImageTo3D(disparity_left_visual,_3dImage,Q); А как из изображения получить z?
-
Ага вроде бы строить карту глубины более менее получается. Для того что бы определять расстояния до точки как я понимаю нужно использовать cvReprojectImageTo3D на выходе будет массив точек, каждая из которых задаётся координатами x, y, z, но что то я не пойму как получить z для конкретного пикселя на изображении.
-
Вожусь с настройкой cvFindStereoCorrespondenceBM уже несколько дней пока мало что получилось. Вопросы: 1)Какое оптимальное расстояние должно быть между камерами, при 7см у меня работает неплохо но при отдалении от камер больше чем на 2 метра начинает показывать всякую чущь 2) Имеет ли значения какая камера правая а какая левая, при калибровке я указываю правой ту камеру которая будет находится справа для меня если я буду смотреть в объективы камерам, а при непосредственно построении карты глубины я считаю правой ту камеру которая находится слева от меня (если смотреть камерам в объектив) как ни странно так результаты получаются лучше
-
Так, отлично камеры мне откалибровать удалось на выходе: D1.xml, D2.xml, M1.xml, M2.xml, mx1.xml, mx2.xml, my1.xml, my2.xml, Q.xml. http://blog.martinperis.com/2011/01/opencv-stereo-camera-calibration.html здесь написано что надо использовать cvRemap для того что бы cvFindStereoCorrespondenceBM работал нормально. Результат cvRemap получается вот такой: а карта глубины вот такая: как видите разница небольшая. CvMat *Q = (CvMat *)cvLoad("Q.xml",NULL,NULL,NULL); CvMat *mx1 = (CvMat *)cvLoad("mx1.xml",NULL,NULL,NULL); CvMat *my1 = (CvMat *)cvLoad("my1.xml",NULL,NULL,NULL); CvMat *mx2 = (CvMat *)cvLoad("mx2.xml",NULL,NULL,NULL); CvMat *my2 = (CvMat *)cvLoad("my2.xml",NULL,NULL,NULL); IplImage *image_ = 0; IplImage *image1_ = 0; CvCapture* capture1 = cvCreateCameraCapture(2); CvCapture* capture2 = cvCreateCameraCapture(1); cvSetCaptureProperty(capture1, CV_CAP_PROP_FRAME_WIDTH, 640); cvSetCaptureProperty(capture1, CV_CAP_PROP_FRAME_HEIGHT, 480); cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_WIDTH, 640); cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_HEIGHT, 480); while(true){ imageLeft= cvQueryFrame( capture2 ); imageRight= cvQueryFrame( capture1 ); CvSize size = cvGetSize(imageRight); IplImage *image_gLeft = cvCreateImage(size, 8,1); IplImage *image_gRight = cvCreateImage( size, 8,1); IplImage *imageTransL= cvCreateImage(size, 8,1); IplImage *imageTransR = cvCreateImage( size, 8,1); IplImage *dstL = cvCreateImage(cvSize(imageLeft->width, imageLeft->height), imageLeft->depth, imageLeft->nChannels); IplImage *dstR = cvCreateImage(cvSize(imageRight->width, imageRight->height), imageRight->depth, imageRight->nChannels); CvMat* disparity_left = cvCreateMat( size.height, size.width, CV_16S ); CvMat* disparity_right = cvCreateMat( size.height, size.width, CV_16S ); cvRemap( imageLeft, dstL, mx1, my1); cvRemap( imageRight, dstR, mx2, my2); cvShowImage("captureRD",dstR); cvShowImage("captureLD",dstL); cvCvtColor( dstL, image_gLeft, CV_BGR2GRAY ); cvCvtColor( dstR, image_gRight, CV_BGR2GRAY ); CvStereoBMState* state = cvCreateStereoBMState( 16, 0); cvFindStereoCorrespondenceBM( image_gRight, image_gLeft, disparity_left, state ); CvMat* disparity_left_visual = cvCreateMat( size.height, size.width,CV_8U ); cvMinMaxLoc(disparity_left, &min_val, &max_val); if(min_val!=max_val) { cvConvertScale(disparity_left, disparity_left_visual,255.0/(max_val-min_val),-min_val/(max_val-min_val)); } cvShowImage("captureL", imageLeft); cvShowImage("captureR",imageRight); cvShowImage("Output",disparity_left_visual); cvReleaseStereoBMState( &state ); } return 0; }
-
Ага как я понял проблема в не параллельности камер то есть надо как то их калибровать. Все программы которые там выложены для Linux.
-
Спасибо. Попробовал сделать все тоже самое с камерами в принципе работает но опять же достаточно плохо int main(array<System::String ^> ^args) { IplImage *image_ = 0; IplImage *image1_ = 0; CvCapture* capture1 = cvCreateCameraCapture(1); CvCapture* capture2 = cvCreateCameraCapture(2); cvSetCaptureProperty(capture1, CV_CAP_PROP_FRAME_WIDTH, 640); cvSetCaptureProperty(capture1, CV_CAP_PROP_FRAME_HEIGHT, 480); cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_WIDTH, 640); cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_HEIGHT, 480); while(true){ image1_= cvQueryFrame( capture2 ); image_= cvQueryFrame( capture1 ); CvSize size = cvGetSize(image_); IplImage *image_g = cvCreateImage(size, 8,1); IplImage *image1_g = cvCreateImage( size, 8,1); CvMat* disparity_left = cvCreateMat( size.height, size.width, CV_16S ); CvMat* disparity_right = cvCreateMat( size.height, size.width, CV_16S ); cvCvtColor( image_, image_g, CV_BGR2GRAY ); cvCvtColor( image1_, image1_g, CV_BGR2GRAY ); CvStereoBMState* state = cvCreateStereoBMState( 16, 0); cvFindStereoCorrespondenceBM( image_g, image1_g, disparity_left, state ); CvMat* disparity_left_visual = cvCreateMat( size.height, size.width,CV_8U ); cvMinMaxLoc(disparity_left, &min_val, &max_val); if(min_val!=max_val) { cvConvertScale(disparity_left, disparity_left_visual,255.0/(max_val-min_val),-min_val/(max_val-min_val)); } cvShowImage("capture1",image_); cvShowImage("capture2",image1_); cvShowImage("Output",disparity_left_visual); cvReleaseStereoBMState( &state ); cvWaitKey(33); } return 0; } А вот такой получается результат: Подумал может кому будет интересно, и сфотографировал своего если можно так сказать робота, пока он гоняется за зелеными шариками но планируется что он будет их собирать для этого и нужно определять расстояние до объекта.
-
Попробовал как вы советовали. cvConvertScale( disparity_left, disparity_left_visual,state->numberOfDisparities); дает не очень хороший результат. Лучше всего получается когда cvConvertScale( disparity_left, disparity_left_visual,1);
-
Ага, на счет калибровки понятно. А вот на счет построения карты глубины не очень, если использовать FindStereoCorrespondenceBM то получается примерно так как на картинке: IplImage *image_ = 0; IplImage *image1_ = 0; image_ = cvLoadImage("left.jpg", 1 ); image1_ = cvLoadImage("right.jpg", 1 ); IplImage *image_g = cvCreateImage( cvSize(image_->width,image_->height), 8,1); IplImage *image1_g = cvCreateImage( cvSize(image_->width,image_->height), 8,1); CvSize size = cvGetSize(image_); CvMat* disparity_left = cvCreateMat( size.height, size.width, CV_16S ); CvMat* disparity_right = cvCreateMat( size.height, size.width, CV_16S ); cvCvtColor( image_, image_g, CV_BGR2GRAY ); cvCvtColor( image1_, image1_g, CV_BGR2GRAY ); CvStereoBMState* state = cvCreateStereoBMState( 16, 0); cvFindStereoCorrespondenceBM( image_g, image1_g, disparity_left, state ); cvReleaseStereoBMState( &state ); CvMat* disparity_left_visual = cvCreateMat( size.height, size.width, CV_8U ); cvConvertScale( disparity_left, disparity_left_visual, -16 ); cvSave( "disparity.png", disparity_left_visual ); cvSaveImage( "disparity.jpg", disparity_left_visual ); return 0; }
-
Здравствуйте! Недавно начал разбираться с OpenCV а конкретно c определением расстояния до какого либо объекта, и возникло несколько вопросов: 1)Как я понимаю первое что надо сделать это построить карту глубины, ее постройка для статичных картинок проблем не вызывает а вот при использовании камер, cvFindStereoCorrespondenceGC работает слишком медленно а cvFindStereoCorrespondenceBM дает слишком плохой результат. 2)Ладно допустим карта глубины построена следующий шаг это нахождение реального расстояния до объекта для этого как я понимаю нужно использовать ReprojectImageTo3D, первый параметр disparityImage который нам создал cvFindStereoCorrespondenceGC() второй параметр IplImage (size, IPL_DEPTH_32F, 3) третий параметр самый интересный... матрица СvMat(4,4, CV_64F), но где ее взять, как я понимаю для этого и нужно калибровать камеры, но как? IplImage *image_ = 0; IplImage *image1_ = 0; int main(array<System::String ^> ^args) { IplImage *image_ = 0; IplImage *image1_ = 0; image_ = cvLoadImage("left.jpg", 1 ); image1_ = cvLoadImage("right.jpg", 1 ); IplImage *image_g = cvCreateImage( cvSize(image_->width,image_->height), 8,1); IplImage *image1_g = cvCreateImage( cvSize(image_->width,image_->height), 8,1); CvSize size = cvGetSize(image_); CvMat* disparity_left = cvCreateMat( size.height, size.width, CV_16S ); CvMat* disparity_right = cvCreateMat( size.height, size.width, CV_16S ); cvCvtColor( image_, image_g, CV_BGR2GRAY ); cvCvtColor( image1_, image1_g, CV_BGR2GRAY ); CvStereoGCState* state = cvCreateStereoGCState( 16, 2); cvFindStereoCorrespondenceGC( image_g, image1_g, disparity_left, disparity_right, state, 0 ); cvReleaseStereoGCState( &state ); CvMat* disparity_left_visual = cvCreateMat( size.height, size.width, CV_8U ); cvConvertScale( disparity_left, disparity_left_visual, -16 ); cvSave( "disparity.png", disparity_left_visual ); cvSaveImage( "disparity.jpg", disparity_left_visual ); return 0; }