reg123321 0 Жалоба Опубликовано June 9, 2013 Почитал информацию на этой ветке форума, спасибо, кое в чем помогла. Карта глубины, например для изображения: у меня уже получается хотя и далекая от идеала: однако когда использую cvReprojectImageTo3D, то получается http://www.4shared.com/download/IZs-VLCL/pict3.JPG?tsid=20130609-143805-5a2a3a37. Причем цвета никак не изменяются при приближении или удалении объектов. Может кто-нибудь с таким сталкивался? int nStereoPreFilterSize; int nStereoPreFilterCap; int nStereoSADWindowSize; int nStereoMinDisparity; int nStereoNumDisparities; int nStereoTextureThreshold; int nStereoUniquenessRatio; 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); void depthMap(IplImage *img0, IplImage *img1, IplImage *Image3D){ CvStereoBMState *state = cvCreateStereoBMState(); state->preFilterSize=nStereoPreFilterSize; state->preFilterCap=nStereoPreFilterCap; state->SADWindowSize=nStereoSADWindowSize; state->minDisparity= nStereoMinDisparity*-16; state->numberOfDisparities=nStereoNumDisparities*16; state->textureThreshold=nStereoTextureThreshold; state->uniquenessRatio=nStereoUniquenessRatio; //double Q[] = { 1., 0., 0., -327.73883438110352, //0., 1., 0.,-239.84486865997314, //0., 0., 0., 524.04542174159019, //0.,0., -0.30009508961926923, 1.2438668093184739 }; //CvMat _Q; //cvInitMatHeader(&_Q,4,4,CV_32FC1,Q); CvSize size = cvGetSize(img0); IplImage *img0_g = cvCreateImage(size, IPL_DEPTH_8U,1); IplImage *img1_g = cvCreateImage(size, IPL_DEPTH_8U,1); CvMat* disp = cvCreateMat( size.height, size.width, CV_16S); IplImage *img0r = cvCreateImage(size, IPL_DEPTH_8U,1); IplImage *img1r = cvCreateImage(size, IPL_DEPTH_8U,1); cvCvtColor( img0, img0_g, CV_BGR2GRAY ); cvCvtColor( img1, img1_g, CV_BGR2GRAY ); //cvRemap( img0_g, img0r, mx1, my1); //cvRemap( img1_g, img1r, mx2, my2); cvFindStereoCorrespondenceBM( img0_g, img1_g,/*img0r, img1r,*/ disp, state ); CvMat* disp_visual = cvCreateMat( size.height, size.width, CV_8U ); cvNormalize( disp, disp_visual, 0, 256, CV_MINMAX ); //double min_val, max_val; //cvMinMaxLoc(disp, &min_val, &max_val); //if(min_val!=max_val) //{ //cvConvertScale(disp, disp_visual, 255.0/(max_val-min_val),-min_val/(max_val-min_val)); //} cvShowImage("difmap", disp_visual); cvReprojectImageTo3D(disp_visual, Image3D, Q/*&_Q*/); cvReleaseMat(&disp); cvReleaseStereoBMState(&state); cvReleaseMat (&disp_visual); cvReleaseImage (&img0r); cvReleaseImage (&img1r); cvReleaseImage(&img0_g); cvReleaseImage(&img1_g); } void myStereoPreFilterSize(int pos) { nStereoPreFilterSize = pos; if( nStereoPreFilterSize % 2 == 0 ) {nStereoPreFilterSize++; pos++;} if( nStereoPreFilterSize < 5 ) nStereoPreFilterSize = 5; } void myStereoPreFilterCap(int pos) { nStereoPreFilterCap = pos; if( nStereoPreFilterCap < 1 ) nStereoPreFilterCap = 1; } void myStereoSADWindowSize(int pos) { nStereoSADWindowSize = pos; if( nStereoSADWindowSize % 2 == 0 ) {nStereoSADWindowSize++; pos++;} if( nStereoSADWindowSize < 5 ) nStereoSADWindowSize = 5; } void myStereoMinDisparity(int pos) { nStereoMinDisparity = pos; if( nStereoMinDisparity < 0) nStereoMinDisparity=0; } void myStereoNumDisparities(int pos) { nStereoNumDisparities = pos; if( nStereoNumDisparities <1 ) nStereoNumDisparities=1; } void myStereoTextureThreshold(int pos) { nStereoTextureThreshold = pos; if( nStereoTextureThreshold < 0 ) nStereoTextureThreshold = 1; } void myStereoUniquenessRatio(int pos) { nStereoUniquenessRatio = pos; if( nStereoUniquenessRatio < 0 ) nStereoUniquenessRatio = 0; } int main(int argc, char* argv[]) { nStereoPreFilterSize = 5; nStereoPreFilterCap = 1; nStereoSADWindowSize = 5; nStereoMinDisparity = 0; nStereoNumDisparities = 1; nStereoTextureThreshold = 1; nStereoUniquenessRatio = 0; CvCapture *capture0 = 0, *capture1 = 0; IplImage *frame0 = 0, *frame1 = 0; IplImage *img = 0, *img1 = 0, *imgContours = 0; capture0 = cvCreateCameraCapture(0); capture1 = cvCreateCameraCapture(1); cvSetCaptureProperty(capture0, CV_CAP_PROP_FRAME_WIDTH, 640);//1280); cvSetCaptureProperty(capture1, CV_CAP_PROP_FRAME_HEIGHT, 480);//960); cvNamedWindow("capture0", CV_WINDOW_AUTOSIZE); cvNamedWindow("capture1", CV_WINDOW_AUTOSIZE); cvNamedWindow("depthmap",CV_WINDOW_AUTOSIZE); cvNamedWindow("difmap",CV_WINDOW_AUTOSIZE); cvNamedWindow("trackBars",CV_WINDOW_AUTOSIZE); cvCreateTrackbar("nStereoPreFilterSize", "trackBars", &nStereoPreFilterSize, 255, myStereoPreFilterSize); cvCreateTrackbar("nStereoPreFilterCa", "trackBars", &nStereoPreFilterCap, 63, myStereoPreFilterCap); cvCreateTrackbar("nStereoSADWindowSize", "trackBars", &nStereoSADWindowSize, 255, myStereoSADWindowSize); cvCreateTrackbar("nStereoMinDisparity", "trackBars", &nStereoMinDisparity, 255, myStereoMinDisparity); cvCreateTrackbar("nStereoNumDisparities", "trackBars", &nStereoNumDisparities, 255, myStereoNumDisparities); cvCreateTrackbar("nStereoTextureThreshold", "trackBars", &nStereoTextureThreshold, 255, myStereoTextureThreshold); cvCreateTrackbar("nStereoUniquenessRatio", "trackBars", &nStereoUniquenessRatio, 255, myStereoUniquenessRatio); int counter = 0; char filename0[512]; char filename1[512]; while(true){ frame0 = cvQueryFrame(capture0); frame1 = cvQueryFrame(capture1); imgContours = cvCreateImage( cvGetSize(frame0), IPL_DEPTH_32F, 3 ); cvShowImage("capture0", frame0); cvShowImage("capture1", frame1); depthMap (frame0, frame1, imgContours); cvShowImage("depthmap", imgContours); char c = cvWaitKey(33); if (c == 27) { // нажата ESC cvReleaseImage(&img); cvReleaseImage(&imgContours); break; } cvReleaseImage(&img); cvReleaseImage(&imgContours); } cvDestroyAllWindows(); cvReleaseCapture(&capture0); cvReleaseCapture(&capture1); return 0; } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 9, 2013 Если на изображении значения приведены к диапазону 0-1, то цвет отражает только относительные расстояния кадра и не будет меняться. Если нет, то у Вас могут быть значения, которые отсекаются (там ведь координаты точек и они не обязательно в диапазоне 0-1). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
reg123321 0 Жалоба Опубликовано June 10, 2013 Если на изображении значения приведены к диапазону 0-1, то цвет отражает только относительные расстояния кадра и не будет меняться. Если нет, то у Вас могут быть значения, которые отсекаются (там ведь координаты точек и они не обязательно в диапазоне 0-1). Простите, я не совсем понял как это сделать, т.е. как сделать, чтобы при удалении или приближении объекта цвет изменялся. Если можно по-конкретнее Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 10, 2013 Возьмите третий слой изображения (который отвечает за Z-координату), остальные заполните нулями или просто отделите нужный канал через split. Определите максимальное (По моему, там при неудачном определении расстояния заносится какое то большое число (вроде 10000), их обнулите.) и минимальное значение. Вычтите из матрицы z-координат минимальное значение. Найдите разность между минимальным и максимальным значением z-координаты. Умножьте её на коэффициент запаса (например 1.5). Запомните его. Из дальнейших кадров вычитайте минимальное значение, найденное ранее и делите на разность, умноженную на коэффициент запаса. Прицепите канал обратно, если нужно (merge). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
reg123321 0 Жалоба Опубликовано June 10, 2013 Выделил третий слой изображения вот так: cvReprojectImageTo3D(disp_visual, Image3D, Q/*&_Q*/); std::vector<cv::Mat> layers(3); split(Image3D, layers); imshow("layer 0", layers[2]); - получил черное изображение. Так должно быть? Максимальное и минимальное значение, все-таки получились разные (-5.8913 и -1.04251). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 10, 2013 Черное, потому что значения отрицательные. Вычтите из этого -5.8913 и разделите на 6. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
reg123321 0 Жалоба Опубликовано June 12, 2013 Для пробы пока написал так: cvReprojectImageTo3D(disp_visual, Image3D, Q/*&_Q*/); std::vector<cv::Mat> layers(3); split(Image3D, layers); CvMat *matrix = cvCreateMat( size.height, size.width, CV_32F); *matrix = layers[2]; static double min_val, max_val; static double mm; if (flag){ cvMinMaxLoc(matrix, &min_val, &max_val); mm = max_val-min_val*1.5; } flag = false; for(int i=0; i<matrix->rows; i++){ double *ptr = (double*)(matrix->data.ptr + i*matrix->step); for(int j=0; j<matrix->cols; j++){ ptr[j] = (ptr[j]-min_val)/mm; } } cv::Mat imgMat(matrix); layers[2] = imgMat; merge(layers, imgMat); imshow("layer 0", imgMat); cvReleaseMat(&matrix); Получил вот такую картинку: http://dc309.4shared.com/img/I79wT-80/s3/0.6733008480756292/pict4.JPG Может быть я что-то делаю неправильно. Если не трудно, разъясните что. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 12, 2013 Да вроде все правильно. При изменении расстояния картинка меняется? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
reg123321 0 Жалоба Опубликовано June 12, 2013 Походу - нет. Остались статичные области желтого, черного и других цветов Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 12, 2013 А, не заметил, cvMinMaxLoc(matrix, &min_val, &max_val); значения максимума, минимума, и т.д. посчитать нужно один раз, иначе ничего меняться и не должно (хотя если считать один раз, это сильно улучшить картинку тоже не должно, скорее наоборот). Может для тестирования просто стенку снять она плоская, с рисунком, и т.д. легче будет понять правильно работает, или нет. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
reg123321 0 Жалоба Опубликовано June 12, 2013 Для вот такой стены: http://dc437.4shared.com/img/XtrHDI_W/s7/0.9864962735823651/pict6.JPG Получается вот это: http://dc437.4shared.com/img/A3FkgYjR/s7/0.6611969847504543/pict5.JPG cvMinMaxLoc(matrix, &min_val, &max_val) Я пока что завел глобальную переменную flag, которая станет после первого прохода false и cvMinMaxLoc не будет работать Я еще, наверное, буду ковыряться, в любом случае, большое спасибо Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
reg123321 0 Жалоба Опубликовано June 13, 2013 Самое главное, что фактически экран разделился на 4 цветовых области. Причем на них никак не влияют ни изменение параметров CvStereoBMState, ни изменения самого изображения. http://dc538.4shared.com/img/JVFqjo6R/s7/0.13688327393514/pict7.jpg Может быть, это из-за параметра Q, однако при всех попытках калибровки камеры с помощью доски у меня получалась подобная картина. Я просто не знаю с чем это может быть связано? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах