Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the OpenCV FindChessboardCorners convention?

Tags:

c

opencv

I'm using OpenCV 2.2.

If I use cvFindChessboardCorners to find the corners of a chessboard, in what order are the corners stored in the variable corners (e.g. top-left corner first, then row then column)?

Documentation (which didn't helped much).

like image 838
JLagana Avatar asked Oct 04 '13 20:10

JLagana


1 Answers

It seems to me the doc is lacking this kind of details.

For 3.2.0-dev it seems to me it depends on the angle of rotation of the chessboard. With this snippet:

cv::Size patternsize(4,3); //number of centers
cv::Mat cal = cv::imread(cal_name);
std::vector<cv::Point2f> centers; //this will be filled by the detected centers

bool found = cv::findChessboardCorners( cal, patternsize, centers, cv::CALIB_CB_ADAPTIVE_THRESH );

std::cout << found << "\n";
if(found){      
    cv::drawChessboardCorners(cal,patternsize,centers,found);

You will get these results:

First image: enter image description here

First image rotated by 180 degrees: enter image description here

Note the

colored corners connected with lines

drawn by drawChessboardCorners, they differ only by the color: in the original image the red line is at the bottom, in the rotated image the red line is at the top of the image. If you pass to drawChessboardCorners a grayscale image you will loose this piece of information.

If I need the first corner at the top left of the image and if I can assume that:

  1. the angle of the chessboard in the scene will be only close to 0 or close to 180;
  2. the tilt of the camera will be negligible;

then the following snippet will reorder the corners if needed:

cv::Size patternsize(4,3); //number of centers
cv::Mat cal = cv::imread(cal_name);
std::vector<cv::Point2f> centers; //this will be filled by the detected centers

bool found = cv::findChessboardCorners( cal, patternsize, centers, cv::CALIB_CB_ADAPTIVE_THRESH );

std::cout << found << "\n";
if(found){      
    cv::drawChessboardCorners(cal,patternsize,centers,found);
    // I need the first corner at top-left
    if(centers.front().y > centers.back().y){
        std::cout << "Reverse order\n";
        std::reverse(centers.begin(),centers.end());
    }
    for(size_t r=0;r<patternsize.height;r++){
        for(size_t c=0;c<patternsize.width;c++){
            std::ostringstream oss;
            oss << "("<<r<<","<<c<<")";
            cv::putText(cal, oss.str(), centers[r*patternsize.width+c], cv::FONT_HERSHEY_PLAIN, 3, CV_RGB(0, 255, 0), 3);
        }
    }
}

enter image description here enter image description here

like image 73
Alessandro Jacopson Avatar answered Nov 05 '22 09:11

Alessandro Jacopson