简体   繁体   中英

OpenCV calibrateCamera assertation failed

few days I'm fighting with camera calibration with chessboard example. Everything is going fine (corners are found and displayed, then feed to arrays) till I call final function calibrateCamera. Than I get assertation error:

OpenCV Error: Assertion failed (nimages > 0) in calibrateCamera, file /home/ig/Downloads/opencv-2.4.8/modules/calib3d/src/calibration.cpp, line 3415

here is classic code:

    #include <iostream>
    #include <fstream>
    #include <vector>

    #include "opencv2/core/core.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/calib3d/calib3d.hpp"
    #include "opencv2/imgproc/imgproc.hpp"

    using namespace cv;
    using namespace std;

    int main(int argc, char* argv[])
    {
        VideoCapture captR(0); // open the video camera no. 0 (RIGHT)

        if (!captR.isOpened())  // if not success, exit program
        {
            cout << "Cannot open the video cam 0" << endl;
            return -1;
        }

        namedWindow("MyVideo (RIGHT)",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"

        namedWindow("Grayscale",CV_WINDOW_AUTOSIZE); //create a window called "Grayscale"

        int a = 0;  // Frame counter

        int numCornersHor = 7; // Chessboard dimensions
        int numCornersVer = 5;
        int numSquares = numCornersHor * numCornersVer;
        Size boardSize = Size(numCornersHor, numCornersVer);

        Mat frameR;
        //      Mat frameL;
        Mat gray_frame;

        vector<Point3f> obj;
        vector<Point2f> corners;  // output vectors of image points

        for (int i=0; i<boardSize.height; i++) {
            for (int j=0; j<boardSize.width; j++) {
                obj.push_back(Point3f(i, j, 0.0f));
            }
        }

        while (1){

            int key = waitKey(30);

            bool bCaptSuccessR = captR.read(frameR); // read a new frame from video

            if (!bCaptSuccessR) //if capture not succeded, break loop
            {
                 cout << "Cannot read a frame from video stream" << endl;
                 break;
            }

            vector<vector<Point3f> > object_points;
            vector<vector<Point2f> > image_points;

            // make grayscale frame version for conerSubPix
            cvtColor(frameR, gray_frame, CV_BGR2GRAY);

            // Get the chessboard corners
            bool found = findChessboardCorners(frameR, boardSize, corners);

            if (found) {
                // Increase accuracy by subpixels
                cornerSubPix(gray_frame, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
                drawChessboardCorners(gray_frame, boardSize, corners, found);
                imshow("Grayscale", gray_frame);

                ////////////////////////////////////////////
                if(key==32){  // Save good found by pressing [space]
                    image_points.push_back(corners);
                    object_points.push_back(obj);
                    cout << "Captured good calibration image, No " << a << endl;
                    cout << "corners: " << corners << endl;
                    //cout << "obj: " << obj << endl;
                    a++;
                }
            }

            imshow("MyVideo (RIGHT)", frameR); //show right webcam frame in "MyVideo" window

            if (key == 27) {    //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
                cout << "esc key is pressed by user" << endl;
                break;
            }

            if (key == 115){ // If 'S' key pressed begin calibration

                //////////// BEGIN CALIBRATION ////////////////////////
                cout << "Callibration started..." << endl;

                Mat cameraMatrix = Mat(3, 3, CV_64F);
                cameraMatrix.at<double>(0,0) = 1.0;

                Mat distCoeffs;
                distCoeffs = Mat::zeros(8, 1, CV_64F);

                vector<Mat> rvecs;
                vector<Mat> tvecs;

                Size imageSize = frameR.size();

                calibrateCamera(object_points, image_points, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);

                cout << "Callibration ended." << endl;



            }//callibration
        }

        captR.release();

        return 0;

    }

And here is OpenCV file excerpt with line numbers:

3400    double cv::calibrateCamera( InputArrayOfArrays _objectPoints,
3401                                InputArrayOfArrays _imagePoints,
3402                                Size imageSize, InputOutputArray _cameraMatrix, InputOutputArray _distCoeffs,
3403                                OutputArrayOfArrays _rvecs, OutputArrayOfArrays _tvecs, int flags, TermCriteria criteria )
3404    {
3405        int rtype = CV_64F;
3406        Mat cameraMatrix = _cameraMatrix.getMat();
3407        cameraMatrix = prepareCameraMatrix(cameraMatrix, rtype);
3408        Mat distCoeffs = _distCoeffs.getMat();
3409        distCoeffs = prepareDistCoeffs(distCoeffs, rtype);
3410        if( !(flags & CALIB_RATIONAL_MODEL) )
3411            distCoeffs = distCoeffs.rows == 1 ? distCoeffs.colRange(0, 5) : distCoeffs.rowRange(0, 5);
3412
3413        int    i;
3414        size_t nimages = _objectPoints.total();
3415        CV_Assert( nimages > 0 );
3416        Mat objPt, imgPt, npoints, rvecM((int)nimages, 3, CV_64FC1), tvecM((int)nimages, 3, CV_64FC1);
3417        collectCalibrationData( _objectPoints, _imagePoints, noArray(),
3418                                objPt, imgPt, 0, npoints );
3419        CvMat c_objPt = objPt, c_imgPt = imgPt, c_npoints = npoints;
3420        CvMat c_cameraMatrix = cameraMatrix, c_distCoeffs = distCoeffs;
3421        CvMat c_rvecM = rvecM, c_tvecM = tvecM;
3422
3423        double reprojErr = cvCalibrateCamera2(&c_objPt, &c_imgPt, &c_npoints, imageSize,
3424                                              &c_cameraMatrix, &c_distCoeffs, &c_rvecM,
3425                                              &c_tvecM, flags, criteria );
3426
3427        bool rvecs_needed = _rvecs.needed(), tvecs_needed = _tvecs.needed();
3428
3429        if( rvecs_needed )
3430            _rvecs.create((int)nimages, 1, CV_64FC3);
3431        if( tvecs_needed )
3432            _tvecs.create((int)nimages, 1, CV_64FC3);
3433

Using Linux Ubuntu 12.04, OpenCV 2.4.8, gcc 4.6.3, Eclipse, ...

You are declaring object_points and image_points within the while loop, but probably want to put declarations outside of the loop. Otherwise, the lists will (effectively) be cleared after each iteration.

The user presses the first key, to detect the checkerboards. Boards are written to object_points and image_points . Then the user presses the key to calibrate the camera. Processing of the first key ends, object_points and image_points loose scope (and are cleared), processing of the second key starts, calibrateCamera is called with an empty object_points array and fails.

You should also check whether object_points is not empty before calling calibrateCamera .

您还可以在OpenCV源库的samples / cpp / tutorial_code / calib3d / camera_calibration /文件夹中找到源代码

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM