OpenCV StereoSGBM gives really bad disparity map

安稳与你 提交于 2019-12-08 10:08:42

问题


these is my calibration code:

  void calibrate()
 {
    int numBoards = 10;
    int board_w = 6;
    int board_h = 9;
    Size board_sz = Size(board_w, board_h);
    int board_n = board_w*board_h;
    vector<vector<Point3f> > object_points;
    vector<vector<Point2f> > imagePoints1, imagePoints2;
    vector<Point2f> corners1, corners2;
    vector<Point3f> obj;
    for (int j=0; j<board_n; j++)
    {
        obj.push_back(Point3f(j/board_w, j%board_w, 0.0f));
    }
    Mat img1, img2, gray1, gray2;
    VideoCapture cap1(0);
    VideoCapture cap2(1);
    int success = 0, k = 0;
    bool found1 = false, found2 = false;
    namedWindow("left 1");
    namedWindow("right 1");
    while (success < numBoards)
    {
        cap1 >> img1;
        cap2 >> img2;

        cvtColor(img1, gray1, CV_BGR2GRAY);
        cvtColor(img2, gray2, CV_BGR2GRAY);
        found1 = findChessboardCorners(img1, board_sz, corners1, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
        found2 = findChessboardCorners(img2, board_sz, corners2, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
        if (found1)
        {
            cornerSubPix(gray1, corners1, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
            drawChessboardCorners(gray1, board_sz, corners1, found1);
        }
        if (found2)
        {
            cornerSubPix(gray2, corners2, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
            drawChessboardCorners(gray2, board_sz, corners2, found2);
        }
        imshow("left 1", img1);
        imshow("right 1", img2);
        k = cv::waitKey(2);
        if(found1) cout<<"found 1"<<endl;
        if(found2) cout<<"found 2"<<endl;
        if(!found1 && !found2) cout<<"no"<<endl;

        if ( found1  && found2)
        {
            imagePoints1.push_back(corners1);
            imagePoints2.push_back(corners2);
            object_points.push_back(obj);
            printf ("Corners stored\n");
            success++;
            if (success >= numBoards)
            {
                break;
            }
        }
    }
    destroyAllWindows();
    printf("Starting Calibration\n");
    Mat CM1 = Mat(3, 3, CV_64FC1);
    Mat CM2 = Mat(3, 3, CV_64FC1);
    Mat D1, D2;
    Mat R, T, E, F;
    stereoCalibrate(object_points, imagePoints1, imagePoints2,
    CM1, D1, CM2, D2, img1.size(), R, T, E, F,
    cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5),
    CV_CALIB_SAME_FOCAL_LENGTH | CV_CALIB_ZERO_TANGENT_DIST);
    FileStorage fs1("mystereocalib.yml", FileStorage::WRITE);
    fs1 << "CM1" << CM1;
    fs1 << "CM2" << CM2;
    fs1 << "D1" << D1;
    fs1 << "D2" << D2;
    fs1 << "R" << R;
    fs1 << "T" << T;
    fs1 << "E" << E;
    fs1 << "F" << F;
    printf("Done Calibration\n");
    printf("Starting Rectification\n");
    Mat R1, R2, P1, P2, Q;
    stereoRectify(CM1, D1, CM2, D2, img1.size(), R, T, R1, R2, P1, P2, Q);
    fs1 << "R1" << R1;
    fs1 << "R2" << R2;
    fs1 << "P1" << P1;
    fs1 << "P2" << P2;
    fs1 << "Q" << Q;
    printf("Done Rectification\n");
    printf("Applying Undistort\n");
    Mat map1x, map1y, map2x, map2y;
    Mat imgU1, imgU2;
    initUndistortRectifyMap(CM1, D1, R1, P1, img1.size(), CV_32FC1, map1x, map1y);
    initUndistortRectifyMap(CM2, D2, R2, P2, img2.size(), CV_32FC1, map2x, map2y);
    printf("Undistort complete\n");

    cap1.release();
    cap2.release();
    return;
 }

And this is my disparity map code with different params:

    int main(int argc, char* argv[])
{
    //calibrate();

    Mat img1, img2;

    VideoCapture cap1 = VideoCapture(0);
    VideoCapture cap2 = VideoCapture(1);

    cap1 >> img1;
    cap2 >> img2;

    Mat Q;
    FileStorage fs("mystereocalib.yml", FileStorage::READ);
    fs["Q"] >> Q;

    Mat CM1, CM2, D1, D2, P1, P2, R1, R2;

    fs["CM1"] >> CM1;
    fs["CM2"] >> CM2;
    fs["D1"] >> D1;
    fs["D2"] >> D2;
    fs["P1"] >> P1;
    fs["P2"] >> P2;
    fs["R1"] >> R1;
    fs["R2"] >> R2;

    fs.release();

    Mat map1x, map1y, map2x, map2y;
    Mat imgU1, imgU2;
    initUndistortRectifyMap(CM1, D1, R1, P1, img1.size(), CV_32FC1, map1x, map1y);
    initUndistortRectifyMap(CM2, D2, R2, P2, img2.size(), CV_32FC1, map2x, map2y);


    while(1) 
    {
    cap1 >> img1;
    cap2 >> img2;

    imshow("img1", img1);
    imshow("img2", img2);
    cv::waitKey(1);

    remap(img1, imgU1, map1x, map1y, INTER_LINEAR, BORDER_CONSTANT, Scalar());
    remap(img2, imgU2, map2x, map2y, INTER_LINEAR, BORDER_CONSTANT, Scalar());


    Mat g1,g2, disp, disp8;

    cvtColor(imgU1, g1, CV_BGR2GRAY);
    cvtColor(imgU2, g2, CV_BGR2GRAY);

    /*StereoSGBM sbm;
    sbm.SADWindowSize = 5;
    sbm.numberOfDisparities = 144;
    sbm.preFilterCap = 63;
    sbm.minDisparity = -39;
    sbm.uniquenessRatio = 10;
    sbm.speckleWindowSize = 100;
    sbm.speckleRange = 32;
    sbm.disp12MaxDiff = 2;
    sbm.fullDP = true;
    sbm.P1 = 216;
    sbm.P2 = 864;
    sbm(g1, g2, disp);*/

    int sadSize = 3;
    StereoSGBM sbm;
    sbm.SADWindowSize = sadSize;
    sbm.numberOfDisparities = 128;//144;
    sbm.preFilterCap = 63;
    sbm.minDisparity = 0; //-39;
    sbm.uniquenessRatio = 10;
    sbm.speckleWindowSize = 100;
    sbm.speckleRange = 32;
    sbm.disp12MaxDiff = 1;
    sbm.fullDP = true;
    sbm.P1 = sadSize*sadSize*4;
    sbm.P2 = sadSize*sadSize*32;
    sbm(g1, g2, disp);

    //StereoSGBM sgbm;
    //sgbm.SADWindowSize = 5;
    //sgbm.numberOfDisparities = 192;
    //sgbm.preFilterCap = 4;
    //sgbm.minDisparity = -64;
    //sgbm.uniquenessRatio = 1;
    //sgbm.speckleWindowSize = 150;
    //sgbm.speckleRange = 2;
    //sgbm.disp12MaxDiff = 10;
    //sgbm.fullDP = false;
    //sgbm.P1 = 600;
    //sgbm.P2 = 2400;
    //sgbm(g1, g2, disp);


    //StereoBM sbm;
    //sbm.state->SADWindowSize = 9;
    //sbm.state->numberOfDisparities = 112;
    //sbm.state->preFilterSize = 5;
    //sbm.state->preFilterCap = 61;
    //sbm.state->minDisparity = -39;
    //sbm.state->textureThreshold = 507;
    //sbm.state->uniquenessRatio = 0;
    //sbm.state->speckleWindowSize = 0;
    //sbm.state->speckleRange = 8;
    //sbm.state->disp12MaxDiff = 1;
    //sbm(g1, g2, disp);


    normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);
    //disp.convertTo(disp8, CV_8U);

    imshow("disp8", disp8);


    }

    waitKey(0);

    return 0;
}

I'm new in OpenCV and image processing, what I'm doing wrong?


回答1:


Try to use this calibration file - https://github.com/foxymop/3DPoseEstimation/blob/master/src/out_camera_data.yml I was trying to calibrate my camera as well, but getting small error is really hard and using this configurations gave me better results than trying to find parameters of my camera (most likely my camera is similar to the one from calibration file). Eventually you may try to not use calibration file at all.



来源:https://stackoverflow.com/questions/28398188/opencv-stereosgbm-gives-really-bad-disparity-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!