Why is calibration result value of stereo camera zoom?

asked 2017-12-26 03:06:40 -0600

kasthe gravatar image

Calibration is carried out using a stereo camera.

However, the result value is output as Zoom.

What I want is to measure the actual distance after calibration.

Help me.

       // global variables
        Size boardSize;
        Size2f squareSize;
        vector<vector<Point2f>> imagePoints1, imagePoints2;
        Size imageSize;
        Mat image1, image2;
        Mat disparityMap;

        // mouse event
        void onMouse(int event, int x, int y, int flags, void* param)
        {
            char text[100];

            uchar disparity = disparityMap.at<uchar>(y, x);
            if (disparity != 0) {
            float baseLength = 60.93;
            float flocalLength = 4.3;
            //Focal length(Pixel) * Baseline(mm) / x2-x1(Pixel) = Z(mm)
            //Z_actual = (b * focal_length) / (x_camL - x_camR)
            //focal_pixel = (focal_mm / sensor_width_mm) * image_width_in_pixels
            //focal_pixel = (image_width_in_pixels * 0.5) / tan(FOV * 0.5 * PI / 180)

                // !!! i want get real distance
            double z = (baseLength * flocalLength) / disparity;

            char szBuffer[50] = { 0, };
            sprintf(szBuffer, "%f", z);


            putText(disparityMap, szBuffer, cvPoint(x, y),
                FONT_HERSHEY_COMPLEX_SMALL, 1.2, cvScalar(0, 0, 255), 1.5, CV_AA);

            printf("%s\n", szBuffer);
        }

        imshow("disparity", disparityMap);
        waitKey(10);
    }

    // find chessboard corners
    int find(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;

        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);

        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));

            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 calibration (find() -> runcalibration())
    bool runCalibration()
    {
        Mat map1, map2, map3, map4;

        vector<vector<Point3f> > objectPoints(1);

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

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

        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);

        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 success = checkRange(cameraMatrix1) && checkRange(distCoeffs1) && checkRange(cameraMatrix2) && checkRange(distCoeffs2);
        if (success) {
            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();


            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);

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

            fs << "R" << R ...
(more)
edit retag flag offensive close merge delete

Comments

To improve the quality of your question, please include sample images, unexpected output image (if any), and simplify your sample code to the shortest code which recreates/displays your issue. Thanks.

opalmirror gravatar imageopalmirror ( 2018-01-31 13:35:18 -0600 )edit