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

Muffo picture Muffo · Aug 1, 2013 · Viewed 9.5k times · Source

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.

Answer

John1024 picture John1024 · Nov 25, 2013

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.