Assertion while trying to calibrate stereo system
Hi all, I haven't touch OpenCV for a while so I am a bit rusty. I am trying to calibrate a stereo system using some code from an OpenCV2.4 example.
Here is the relevant code:
if( imagePoints1_[0].size() < nbrOfSample_ )
{
int found1 {0}, found2 {0}; // Stores the result of the function to find corners
cv::Size cvBoardSize {squareW_, squareH_}; // Size of the board in square
cv::Mat imgMat1( origin1_ );
cv::Mat imgMat2( origin2_ );
cv::Mat cimg1;
cv::Mat cimg2;
cv::cvtColor( imgMat1, cimg1, CV_BGR2GRAY );
cv::cvtColor( imgMat2, cimg2, CV_BGR2GRAY );
found1 = cv::findChessboardCorners( cimg1, cvBoardSize, corners1_,
CV_CALIB_CB_ADAPTIVE_THRESH |
CV_CALIB_CB_NORMALIZE_IMAGE );
found2 = cv::findChessboardCorners( cimg2, cvBoardSize, corners2_,
CV_CALIB_CB_ADAPTIVE_THRESH |
CV_CALIB_CB_NORMALIZE_IMAGE );
if( found1 && found2 )
{
cv::cornerSubPix( cimg1, corners1_, cvSize(11, 11), cvSize(-1, -1),
cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,
30, 0.01) );
cv::cornerSubPix( cimg2, corners2_, cvSize(11, 11), cvSize(-1, -1),
cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,
30, 0.01) );
cv::drawChessboardCorners( imgMat1, cvBoardSize, corners1_, found1 );
cv::drawChessboardCorners( imgMat2, cvBoardSize, corners2_, found2 );
if( takeSample_ ) // The user asked to take a sample
{
// The number of corners found in correct
if( true/*(nbrCornersL == nbrOfSquare_) && (nbrCornersR == nbrOfSquare_)*/ )
{
imagePoints1_[0].push_back( corners1_ );
imagePoints1_[1].push_back( corners2_ );
cout << "Sample acquired (" << imagePoints1_[0].size() << "/" <<
nbrOfSample_ << ")" << endl;
}
// else
// CL_PRINT( "Bad sample, start again ..." );
takeSample_ = false;
}
}
cv::imshow( "Calibration image1", imgMat1 );
cv::imshow( "Calibration image2", imgMat2 );
}
else
{
CLVector<CLVector<cv::Point3f>> objectPoints;
imagePoints1_[0].resize( nbrOfSample_ );
imagePoints1_[1].resize( nbrOfSample_ );
objectPoints.resize( nbrOfSample_ );
cv::Size imageSize {width_, height_};
for( int i = 0; i < nbrOfSample_; i++ )
{
for( int j = 0; j < squareH_; j++ )
for( int k = 0; k < squareW_; k++ )
objectPoints[i].push_back( cv::Point3f(j*squareSize_, k*squareSize_, 0) );
}
std << imagePoints1_[0].size() << endl;
std << imagePoints1_[0].front().size() << endl;
std << imagePoints1_[1].size() << endl;
std << imagePoints1_[1].front().size() << endl;
std << objectPoints.size() << endl;
std << objectPoints.front().size() << endl;
std << "Running stereo calibration ..." << endl;
cv::Mat cameraMatrix[2], distCoeffs[2];
cameraMatrix[0] = cv::Mat::eye( 3, 3, CV_64F );
cameraMatrix[1] = cv::Mat::eye( 3, 3, CV_64F );
cv::Mat R, T, E, F;
double rms = cv::stereoCalibrate( objectPoints,
imagePoints1_[0], imagePoints1_[1],
cameraMatrix[0], distCoeffs[0],
cameraMatrix[1], distCoeffs[1],
imageSize, R, T, E, F,
cv::TermCriteria(
CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,
100, 1e-5),
CV_CALIB_FIX_ASPECT_RATIO +
CV_CALIB_ZERO_TANGENT_DIST +
CV_CALIB_SAME_FOCAL_LENGTH +
CV_CALIB_RATIONAL_MODEL +
CV_CALIB_FIX_K3 + CV_CALIB_FIX_K4 +
CV_CALIB_FIX_K5 );
}
This method is called in a loop that grabs the images. So if I don't have enough samples (20) It keeps going, otherwise I go through the calibration process.
Knowing that the important members are:
int width_;
int height_;
const int squareW_;
const int squareH_;
const float squareSize_;
const int nbrOfSample_;
IplImage* origin1_;
IplImage* origin2_;
CLVector<cv::Point2f> corners1_;
CLVector<cv::Point2f> corners2_;
CLVector<CLVector<cv::Point2f>> imagePoints1_[2];
The program crashes and says:
OpenCV Error: Assertion failed (i < 0) in getMat, file /build/buildd/opencv-2.4.2+dfsg/modules/core/src/matrix.cpp, line 957
terminate called after throwing an instance of 'cv::Exception'
what(): /build/buildd/opencv-2.4.2+dfsg/modules/core/src/matrix.cpp:957: error: (-215) i < 0 in function getMat
This is still work in progress, so I apologize if there is ...
Use the debugger to find the method that causes the exception.
I already know that it comes from
stereoCalibrate
.It could be that it wants your imagePoints and objectpoints vectors not in CLVector, but std::vector format. Or it has a problem with your uninitialized distcoeffs. I have never used the method, so I don't know what all those parameters do.
Hahahahahah. At first I was like "this is not a really useful answer." But I was wrong ! I should learn to be more respectful about the answers people give. There is the reason: CLVector is a vector class that derives from std::vector without any additional functionality for now. I don't know why but this function accept the std::vector but not the homemade wrapper (I need to look deeper in the code why). So thank you very much for this useful answer.