我尝试使用opencv来校准立体相机

时间:2017-11-08 02:32:02

标签: c++ opencv calibration

我尝试使用opencv来校准立体相机。

但是,屏幕没有正常显示。

我使用“findChessboardCorners”访问了角落。

确认结果坐标正常。

通过“stereoCalibrate”函数输出参数,

使用参数输出到屏幕。

然而,它没有正常输出。

是什么原因?

// call the function
FindChessboard(matImg1, matImg2, true);

const Size boardSize;
const Size2f squareSize;
vector<vector<Point2f>> imagePoints1, imagePoints2;
Size imageSize;
Mat map1, map2, map3, map4;

// Retrieves the corner
int FindChessboard (Mat view1, Mat view2, bool reg)
{
    if (view1.empty()) {
        return 0;
    }

    if (view2.empty()) {
        return 0;
    }

    assert (view1.size() == view2.size());
    imageSize = view1.size();

    Mat viewGray1, viewGray2;
    cvtColor (view1, viewGray1, CV_BGR2GRAY); 
    cvtColor (view2, viewGray2, CV_BGR2GRAY); 

    vector<Point2f> pointbuf1, pointbuf2;

    // Find the corner
    bool found1 = findChessboardCorners(view1, boardSize, pointbuf1,
        CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);

    bool found2 =  findChessboardCorners(view2, boardSize, pointbuf2,
        CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);

    // find
    if (found1 && found2) {
        // improve the found corners' coordinate accuracy
        cornerSubPix (viewGray1, pointbuf1, Size(11,11), Size(-1,-1), TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
        cornerSubPix (viewGray2, pointbuf2, Size(11,11), Size(-1,-1), TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));

        // push corner position
        if (reg) {
            imagePoints1.push_back (pointbuf1);
            imagePoints2.push_back (pointbuf2);
        }
        drawChessboardCorners (view1, boardSize, Mat(pointbuf1), found1);
        drawChessboardCorners (view2, boardSize, Mat(pointbuf2), found2);
    }

    return imagePoints1.size();
}

以上功能用于获得角落。

// start callibration
bool RunCalibration ()
{
    int size = imagePoints1.size();

    vector<vector<Point3f> > objectPoints;
    objectPoints.resize(size);

    // ..??
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < boardSize.height; j++)
            for (int k = 0; k < boardSize.width; k++)
                objectPoints[i].push_back(Point3f(k*squareSize.width, j*squareSize.height, 0));
    }


    objectPoints.resize(imagePoints1.size(), objectPoints[0]);

    //
    // 좌우 camera의 체스판 영상의 점들로부터 camera matrix, distortion coefficients와 R, P 행렬을 계산한다
    //

    Mat cameraMatrix1 = Mat::eye(3, 3, CV_64F);
    Mat cameraMatrix2 = Mat::eye(3, 3, CV_64F);
    Mat distCoeffs1   = Mat::zeros(8, 1, CV_64F);
    Mat distCoeffs2   = Mat::zeros(8, 1, CV_64F);
    Mat R, T, E, F;

    //cameraMatrix1 = initCameraMatrix2D(objectPoints, imagePoints1, imageSize, 0);
    //cameraMatrix2 = initCameraMatrix2D(objectPoints, imagePoints2, imageSize, 0);

    // start calibration
    double rms = stereoCalibrate(objectPoints, imagePoints1, imagePoints2,
        cameraMatrix1, distCoeffs1,
        cameraMatrix2, distCoeffs2,
        imageSize, R, T, E, F,
        CALIB_FIX_ASPECT_RATIO +
        CALIB_ZERO_TANGENT_DIST +
        CALIB_USE_INTRINSIC_GUESS +
        CALIB_SAME_FOCAL_LENGTH +
        CALIB_RATIONAL_MODEL +
        CALIB_FIX_K3 + CALIB_FIX_K4 + CALIB_FIX_K5,
        TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, 1e-5));

    bool ok = checkRange(cameraMatrix1) && checkRange(distCoeffs1) && checkRange(cameraMatrix2) && checkRange(distCoeffs2);
    if (ok) {
        Mat R1, R2, P1, P2, Q;
        Rect validRoi1, validRoi2;


        stereoRectify (cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
            imageSize, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, 1, imageSize, &validRoi1, &validRoi2);

        // save intrinsic parameters
        FileStorage fs("D:\\Sources\\trunk\\Sources\\Stereo_Scopic\\intrinsics.yml", CV_STORAGE_WRITE);
        if (!fs.isOpened()) return false;

        fs << "M1" << cameraMatrix1;
        fs << "D1" << distCoeffs1;
        fs << "M2" << cameraMatrix2;
        fs << "D2" << distCoeffs2;
        fs.release();

        fs.open("D:\\Sources\\trunk\\Sources\\Stereo_Scopic\\extrinsics.yml", CV_STORAGE_WRITE);
        if (!fs.isOpened()) return false;

        fs << "R" << R;
        fs << "T" << T;
        fs << "R1" << R1;
        fs << "R2" << R2;
        fs << "P1" << P1;
        fs << "P2" << P2;
        fs << "Q" << Q;
        fs << "imageSize" << imageSize;
        fs.release();

        initUndistortRectifyMap (cameraMatrix1, distCoeffs1, R1, P1, imageSize, CV_16SC2, map1, map2);
        initUndistortRectifyMap (cameraMatrix2, distCoeffs2, R2, P2, imageSize, CV_16SC2, map3, map4);
    }

    return ok;
}


// show
int distortionCorrection(Mat leftImg, Mat rightImg) {
    float scale = 1.f;
    Mat img1 = leftImg.clone();
    Mat img2 = rightImg.clone();

    Size img_size = img1.size();

    string intrinsic_filename = "D:\\Sources\\trunk\\Sources\\Stereo_Scopic\\intrinsics.yml";
    string extrinsic_filename = "D:\\Sources\\trunk\\Sources\\Stereo_Scopic\\extrinsics.yml";
    Mat Q;
    Rect roi1, roi2;

    // load parameters
    if (!intrinsic_filename.empty())
    {
        // reading intrinsic parameters
        Mat cameraMatrix1 = Mat::eye(3, 3, CV_64F);
        Mat cameraMatrix2 = Mat::eye(3, 3, CV_64F);
        Mat distCoeffs1 = Mat::zeros(8, 1, CV_64F);
        Mat distCoeffs2 = Mat::zeros(8, 1, CV_64F);

        FileStorage fs("D:\\Sources\\trunk\\Sources\\Stereo_Scopic\\intrinsics.yml", CV_STORAGE_READ);
        if (!fs.isOpened()) return false;

        fs["M1"] >> cameraMatrix1;
        fs["D1"] >> distCoeffs1;
        fs["M2"] >> cameraMatrix2;
        fs["D2"] >> distCoeffs2;

        //read extrinsic parameters
        Mat R, T;
        Mat R1, R2, P1, P2, Q;
        Rect validRoi1, validRoi2;

        fs.open("D:\\Sources\\trunk\\Sources\\Stereo_Scopic\\extrinsics.yml", CV_STORAGE_READ);
        if (!fs.isOpened()) return false;

        fs["R"] >> R;
        fs["T"] >> T;
        fs["R1"] >> R1;
        fs["P1"] >> P1;
        fs["R2"] >> R2;
        fs["P2"] >> P2;
        fs["Q"] >> Q;
        FileNode is = fs["imageSize"];
        img_size.width = is[0];
        img_size.height = is[1];

        Mat map11, map12, map21, map22;

        initUndistortRectifyMap(cameraMatrix1, distCoeffs1, R1, P1, img_size, CV_16SC2, map11, map12);
        initUndistortRectifyMap(cameraMatrix2, distCoeffs2, R2, P2, img_size, CV_16SC2, map21, map22);

        Mat img1r, img2r;
        remap(img1, img1r, map11, map12, INTER_LINEAR);
        remap(img2, img2r, map21, map22, INTER_LINEAR);

        img1 = img1r;
        img2 = img2r;


        namedWindow("img1m", 1);
        imshow("img1m", img1);
        namedWindow("img2m", 1);
        imshow("img2m", img2);

        waitKey(10);

        //stereo(img1, img2);
    }
}

enter image description here

0 个答案:

没有答案