Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV findChessboardCorners function is failing in a (apparently) simple scenario

I'm trying to find the corners of a chessboard using OpenCV.

The image I'm using contains two chessboards, but I'm interested only in a sub-region of one of those. The following image shows the original image.

Original image

Using GIMP, I've then selected the area of interest and I've set all the other pixel to a default value.

Cropped image

I haven't actually cropped the image because I've already calibrated the camera using this image size and I didn't want to change it. The operation should be equivalent to change the values in the image matrix, but I preferred to do it with GIMP. It is a one time experiment and it is faster to do that operation with a graphic tool instead of using the code.

The resulting image contains a chessboard with 24x5 corners, but the function findChessboardCorners is not able to find anything.

Here is the Python code I'm using:

>>> img = cv2.imread('C:\\Path\\To\\C4-Cropped.png', 0)
>>> cv2.findChessboardCorners(img, (24, 5))
(False, None)
>>> cv2.findChessboardCorners(img, (5, 24))
(False, None)

I also tried to set the adaptive threshold, but it is still not working

>>> cv2.findChessboardCorners(img, (24, 5), flags=cv2.cv.CV_CALIB_CB_ADAPTIVE_THRESH)
(False, None)

That seems really strange. I used this function of OpenCV many times in the past and it always worked, even with images that looked much more complicated than this one. The illumination of the area is not homogeneous but the function should be robust enough to handle that.

Is there any problem with the artificial image created ad hoc with GIMP? How can I find the corners?

Any suggestion would be greatly appreciated.

like image 551
Muffo Avatar asked Aug 01 '13 12:08

Muffo


3 Answers

There are two changes needed to make that image acceptable to the very finicky cv2.findChessboardCorners function. First, the chess board needs a white background. I obtained this simply by adjusting the contrast on your image. Second, I also had to white-out the dark horizontal line that connects the black squares at the top and bottom of your chess board. This is the resulting image: enter image description here

With these enhancements, cv2.findChessboardCorners can successfully analyze the image. The results were:

camera matrix =
    [[  1.67e+04   0.00e+00   1.02e+03]
    [  0.00e+00   1.70e+04   5.45e+02]
    [  0.00e+00   0.00e+00   1.00e+00]]

distortion coefficients = [ -4.28e+00   1.38e+03  -8.59e-03  -1.49e-02   6.93e+00]

(Small changes to how the image is enhanced can change the above results greatly. With only one image of a small chess board, these results are not to be trusted.)

As you noted, cv2.findChessboardCorners accepts flags (adaptive threshold, filter_quads, and normalization) that are intended to help with chess board recognition. I tried all but they made no difference here.

like image 143
John1024 Avatar answered Oct 21 '22 12:10

John1024


I bet you $5 that the image thresholding inside findChessboardCorners is producing garbage because of the background in the masked image.

I recommend doing a crop, extracting the chessboard, then offsetting the coordinates of the found corners by the crop window position.

like image 42
Francesco Callari Avatar answered Oct 21 '22 11:10

Francesco Callari


Add white space around the chess pattern. "Note: The function requires white space (like a square-thick border, the wider the better) around the board to make the detection more robust in various environments. Otherwise, if there is no border and the background is dark, the outer black squares cannot be segmented properly and so the square grouping and ordering algorithm fails. "

like image 31
Javier Barandiaran Martirena Avatar answered Oct 21 '22 10:10

Javier Barandiaran Martirena