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.