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

Расстояние до объекта

Recommended Posts

Почитал информацию на этой ветке форума, спасибо, кое в чем помогла.

Карта глубины, например для изображения: pict1.JPG?tsid=20130609-143640-fa59e801, у меня уже получается хотя и далекая от идеала: pict2.JPG?tsid=20130609-143721-552cf86b, однако когда использую 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;

}


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


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

Если на изображении значения приведены к диапазону 0-1, то цвет отражает только относительные расстояния кадра и не будет меняться.

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

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


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

Если на изображении значения приведены к диапазону 0-1, то цвет отражает только относительные расстояния кадра и не будет меняться.

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

Простите, я не совсем понял как это сделать, т.е. как сделать, чтобы при удалении или приближении объекта цвет изменялся. Если можно по-конкретнее

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


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

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

Определите максимальное (По моему, там при неудачном определении расстояния заносится какое то большое число (вроде 10000), их обнулите.) и минимальное значение.

Вычтите из матрицы z-координат минимальное значение.

Найдите разность между минимальным и максимальным значением z-координаты.

Умножьте её на коэффициент запаса (например 1.5).

Запомните его.

Из дальнейших кадров вычитайте минимальное значение, найденное ранее и делите на разность, умноженную на коэффициент запаса.

Прицепите канал обратно, если нужно (merge).

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


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

Выделил третий слой изображения вот так:


cvReprojectImageTo3D(disp_visual, Image3D, Q/*&_Q*/);

std::vector<cv::Mat> layers(3);

split(Image3D, layers);

imshow("layer 0", layers[2]);

- получил черное изображение. Так должно быть?

Максимальное и минимальное значение, все-таки получились разные (-5.8913 и -1.04251).

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


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

Черное, потому что значения отрицательные.

Вычтите из этого -5.8913 и разделите на 6.

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


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

Для пробы пока написал так:


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

Может быть я что-то делаю неправильно. Если не трудно, разъясните что.

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


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

Да вроде все правильно.

При изменении расстояния картинка меняется?

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


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

Походу - нет. Остались статичные области желтого, черного и других цветов

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


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

А, не заметил,

cvMinMaxLoc(matrix, &min_val, &max_val);

значения максимума, минимума, и т.д. посчитать нужно один раз, иначе ничего меняться и не должно (хотя если считать один раз, это сильно улучшить картинку тоже не должно, скорее наоборот).

Может для тестирования просто стенку снять она плоская, с рисунком, и т.д. легче будет понять правильно работает, или нет.

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


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

Для вот такой стены:

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 не будет работать

Я еще, наверное, буду ковыряться, в любом случае, большое спасибо

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


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

Самое главное, что фактически экран разделился на 4 цветовых области. Причем на них никак не влияют ни изменение параметров CvStereoBMState, ни изменения самого изображения.

http://dc538.4shared.com/img/JVFqjo6R/s7/0.13688327393514/pict7.jpg

Может быть, это из-за параметра Q, однако при всех попытках калибровки камеры с помощью доски у меня получалась подобная картина. Я просто не знаю с чем это может быть связано?

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×