JLagana
JLagana

Reputation: 1294

What is the OpenCV FindChessboardCorners convention?

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).

Upvotes: 10

Views: 9228

Answers (2)

Alessandro Jacopson
Alessandro Jacopson

Reputation: 18665

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

Upvotes: 4

WildCrustacean
WildCrustacean

Reputation: 5966

I am pretty sure it orders the chessboard corners by rows, starting with the one closest to the top-left corner of the image.

The chessboard pattern has no specified origin (one of the deficiencies of that calibration device), so if you turn it 90 or 180 degrees the corners you get back won't be in the same order.

The way to make sure is to look at the actual point values you get back and see if they are what you expected.

Edit: at least in case of OpenCV 3.3.1 and 5x3 chessboard, the chessboard corners can be returned either starting top-left or bottom-right, depending on the rotation.

Upvotes: 0

Related Questions