OpenCV calibrateCamera - assertion failed (nimages > 0 && nimages == (int)imagePoints1.total()

admin

Administrator
Staff member
The complete error:

Code:
OpenCV Error: Assertion failed (nimages > 0 && nimages == 
(int)imagePoints1.total() && (!imgPtMat2 || nimages == 
(int)imagePoints2.total())) in collectCalibrationData, file C:\OpenCV
\sources\modules\calib3d\src\calibration.cpp, line 3164

The code:

Code:
cv::VideoCapture kalibrowanyPlik;   //the video

cv::Mat frame;
cv::Mat testTwo; //undistorted
cv::Mat cameraMatrix = (cv::Mat_<double>(3, 3) << 2673.579, 0, 1310.689, 0, 2673.579, 914.941, 0, 0, 1);
cv::Mat distortMat = (cv::Mat_<double>(1, 4) << -0.208143,  0.235290,  0.001005,  0.001339);
cv::Mat intrinsicMatrix = (cv::Mat_<double>(3, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
cv::Mat distortCoeffs = cv::Mat::zeros(8, 1, CV_64F);
//there are two sets for testing purposes. Values for the first two came from GML camera calibration app. 

std::vector<cv::Mat> rvecs;
std::vector<cv::Mat> tvecs;
std::vector<std::vector<cv::Point2f> > imagePoints;
std::vector<std::vector<cv::Point3f> > objectPoints;

kalibrowanyPlik.open("625.avi");
    //cv::namedWindow("Distorted", CV_WINDOW_AUTOSIZE); //gotta see things
    //cv::namedWindow("Undistorted", CV_WINDOW_AUTOSIZE);

int maxFrames = kalibrowanyPlik.get(CV_CAP_PROP_FRAME_COUNT);    
int success = 0;    //so we can do the calibration only after we've got a bunch

for(int i=0; i<maxFrames-1; i++) {    
    kalibrowanyPlik.read(frame);
    std::vector<cv::Point2f> corners; //creating these here so they're effectively reset each time
    std::vector<cv::Point3f> objectCorners;

    int sizeX = kalibrowanyPlik.get(CV_CAP_PROP_FRAME_WIDTH); //imageSize
    int sizeY = kalibrowanyPlik.get(CV_CAP_PROP_FRAME_HEIGHT);

    cv::cvtColor(frame, frame, CV_BGR2GRAY); //must be gray

    cv::Size patternsize(9,6); //interior number of corners

    bool patternfound = cv::findChessboardCorners(frame, patternsize, corners, cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE + cv::CALIB_CB_FAST_CHECK); //finding them corners

    if(patternfound == false) { //gotta know 
        qDebug() << "failure";
    }
    if(patternfound) {
        qDebug() << "success!";
            std::vector<cv::Point3f> objectCorners; //low priority issue - if I don't do this here, it becomes empty. Not sure why. 
            for(int y=0; y<6; ++y) {
                for(int x=0; x<9; ++x) { 
                    objectCorners.push_back(cv::Point3f(x*28,y*28,0)); //filling the array
                }
            }

            cv::cornerSubPix(frame, corners, cv::Size(11, 11), cv::Size(-1, -1),
            cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));

            cv::cvtColor(frame, frame, CV_GRAY2BGR); //I don't want gray lines

            imagePoints.push_back(corners); //filling array of arrays with pixel coord array
            objectPoints.push_back(objectCorners); //filling array of arrays with real life coord array, or rather copies of the same thing over and over
            cout << corners << endl << objectCorners;
            cout << endl << objectCorners.size() << "___" << objectPoints.size() <<  "___" << corners.size() <<  "___" << imagePoints.size() << endl;
            cv::drawChessboardCorners(frame, patternsize, cv::Mat(corners), patternfound); //drawing. 

            if(success > 5) {
                double rms =  cv::calibrateCamera(objectPoints, corners, cv::Size(sizeX, sizeY), intrinsicMatrix, distortCoeffs, rvecs, tvecs, cv::CALIB_USE_INTRINSIC_GUESS); 
//error - caused by passing CORNERS instead of IMAGEPOINTS. Also, imageSize is 640x480, and I've set the central point to 1310... etc
                cout << endl << intrinsicMatrix << endl << distortCoeffs << endl;
                cout << "\nrms - " << rms << endl;
            }
            success = success + 1;

        //cv::imshow("Distorted", frame);
        //cv::imshow("Undistorted", testTwo);
        }
    }

I've done a little bit of reading <a href="https://adventuresandwhathaveyou.wordpress.com/2014/03/14/opencv-error-messages-suck/" rel="nofollow noreferrer">(This was an especially informative read)</a>, including over a dozen threads made here on StackOverflow, and all I found is that this error is produced by either by uneven imagePoints and objectPoints or by them being partially null or empty or zero (and links to tutorials that don't help). None of that is the case - the output from .size() check is:

Code:
54___7___54___7

For objectCorners (real life coords), objectPoints (number of arrays inserted) and the same for corners (pixel coords) and imagePoints. They're not empty either, the output is:

Code:
(...)
277.6792, 208.92903;
241.83429, 208.93048;
206.99866, 208.84637;
(...)
84, 56, 0;
112, 56, 0;
140, 56, 0;
168, 56, 0;
(...)

A sample frame:
<img src=" " alt="enter image description here">

I know it's a mess, but so far I'm trying to complete the code rather than get an accurate reading.

Each one hs exactly 54 lines of that. Does anyone have any ideas on what is causing the error? I'm using OpenCV 2.4.8 and Qt Creator 5.4 on Windows 7.