Ask Your Question
0

camera calibration opencv error

asked 2012-09-22 02:45:24 -0600

Nabeel gravatar image

updated 2012-09-22 15:00:52 -0600

I am doing camera calibration using opencv. I am using the same code given in "Cook book programming".

I am taking pictures from my smartphone of a chessboard. Then I am using opencv program to do camera calibration for me. Program worked for only one set of images when I have very large chess board (size 30 x 30). It does not work for other set of images and I get run time error "Assertion failed <ncorners> =0 . . ."

I dont know what going wrong in my code. The code is as follows:-

int main()
{
CameraCalibrator calibrateCam;
std::vector<std::string> filelist;
char buff[100];

for(int i=0;i<21;i++)
{
    sprintf(buff,"..\\Train\\3\\%d.jpg",i+1);
    filelist.push_back(buff);
}
cv::Size boardSize(4,3);
double calibrateError;
int success;
success = calibrateCam.addChessboardPoints(filelist,boardSize);
}

class CameraCalibrator{
public:
   std::vector<std::vector<cv::Point3f>> objectPoints;
   std::vector<std::vector<cv::Point2f>> imagePoints;
   //Square Lenght
   float squareLenght;
   //output Matrices
   cv::Mat cameraMatrix; //intrinsic
   cv::Mat distCoeffs;
   //flag to specify how calibration is done
   int flag;
   //used in image undistortion
   cv::Mat map1,map2;
   bool mustInitUndistort;
public:
    CameraCalibrator(): flag(0), squareLenght(36.0), mustInitUndistort(true){};
    int addChessboardPoints(const std::vector<std::string>& filelist,cv::Size& boardSize){
        std::vector<std::string>::const_iterator itImg;
        std::vector<cv::Point2f> imageCorners;
        std::vector<cv::Point3f> objectCorners;
        //initialize the chessboard corners in the chessboard reference frame
        //3d scene points
        for(int i = 0; i<boardSize.height; i++){
            for(int j=0;j<boardSize.width;j++){
                objectCorners.push_back(cv::Point3f(float(i)*squareLenght,float(j)*squareLenght,0.0f));
            }
        }
        //2D Image points:
        cv::Mat image; //to contain chessboard image
        int successes = 0;

        for(itImg=filelist.begin(); itImg!=filelist.end(); itImg++){
            image = cv::imread(*itImg,CV_LOAD_IMAGE_GRAYSCALE);
            std::cout<<*itImg<<"\n";

            bool found = cv::findChessboardCorners(image, boardSize, imageCorners);

            cv::drawChessboardCorners(image, boardSize, imageCorners, found);                      
            cv::cornerSubPix(image, imageCorners, cv::Size(5,5),cv::Size(-1,-1),
                cv::TermCriteria(cv::TermCriteria::MAX_ITER+cv::TermCriteria::EPS,30,0.1));
            //if we have a good board, add it to our data
            if(imageCorners.size() == boardSize.area()){
                addPoints(imageCorners,objectCorners);
                successes++;
            }
        }

        return successes;
    }
    void addPoints(const std::vector<cv::Point2f>& imageCorners,const std::vector<cv::Point3f>& objectCorners){
        //2D image point from one view
        imagePoints.push_back(imageCorners);
        //corresponding 3D scene points
        objectPoints.push_back(objectCorners);
    }
    double calibrate(cv::Size &imageSize){
        mustInitUndistort = true;
        std::vector<cv::Mat> rvecs,tvecs;
        return
            cv::calibrateCamera(objectPoints, //the 3D points
                imagePoints,
                imageSize, 
                cameraMatrix, //output camera matrix
                distCoeffs,
                rvecs,tvecs,
                flag);

    }
    void remap(const cv::Mat &image, cv::Mat &undistorted){
        std::cout << cameraMatrix;
        if(mustInitUndistort){ //called once per calibration
            cv::initUndistortRectifyMap(
                cameraMatrix,
                distCoeffs,
                cv::Mat(),
                cameraMatrix,
                image.size(),
                CV_32FC1,
                map1,map2);
            mustInitUndistort = false;
        }
        //apply mapping functions
        cv::remap(image,undistorted,map1,map2,cv::INTER_LINEAR);
    }
};

In camera calibration class, it fails on findChessboardCorners line . . .

I think it cannot find the corners. Plz help me in that. One sample chess board image is as follows. It fails on this image . . . image description

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2012-09-24 01:28:49 -0600

Jacek gravatar image

I think boardSize is incorrect in your code. boardSize should be equal to a number of internal corners, so in your case it should be cv::Size boardSize(5,4).

edit flag offensive delete link more

Comments

yup, Jacek is right. The board size should be 5x4.

Martin Peris gravatar imageMartin Peris ( 2012-09-24 01:49:35 -0600 )edit

Question Tools

Stats

Asked: 2012-09-22 02:45:24 -0600

Seen: 3,131 times

Last updated: Sep 24 '12