My approach for the problem is to perform color-segmentation to get a binary mask. Next, using binary mask to remove the background to make the board visible, removed from artifacts. Finally output the chess border features in an accurate way.
-
- Performing color-segmentation: We convert the loaded image to the HSV format define lower/upper ranges and perform color segmentation using
cv2.inRangeto obtain a binary mask.
- Performing color-segmentation: We convert the loaded image to the HSV format define lower/upper ranges and perform color segmentation using
-
- Extracting chess-board: After obtaining binary mask we will use it to remove the background and separate chess part from the rest of the image using
cv2.bitwise_and. Arithmetic operation and is highly useful for defining roi in hsv colored images.
- Extracting chess-board: After obtaining binary mask we will use it to remove the background and separate chess part from the rest of the image using
-
- Displaying chess-board features. After extracting the chessboard from the image, we will set the
patternSizeto (7, 7) andflagsto adaptive_thresh + fast_check + normalize image inspired from the source.
- Displaying chess-board features. After extracting the chessboard from the image, we will set the
Steps:
Color-segmentation to get the binary mask.

-
lwr = np.array([0, 0, 143]) upr = np.array([179, 61, 252]) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) msk = cv2.inRange(hsv, lwr, upr)
Removing background using mask

-
krn = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 30)) dlt = cv2.dilate(msk, krn, iterations=5) res = 255 - cv2.bitwise_and(dlt, msk)
Displaying Chess-board features

-
res = np.uint8(res) ret, corners = cv2.findChessboardCorners(res, (7, 7), flags=cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE) if ret: print(corners) fnl = cv2.drawChessboardCorners(img, (7, 7), corners, ret) cv2.imshow("fnl", fnl) cv2.waitKey(0) else: print("No Checkerboard Found")
Code:
import cv2
import numpy as np
# Load the image
img = cv2.imread("kFM1C.jpg")
# Color-segmentation to get binary mask
lwr = np.array([0, 0, 143])
upr = np.array([179, 61, 252])
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
msk = cv2.inRange(hsv, lwr, upr)
# Extract chess-board
krn = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 30))
dlt = cv2.dilate(msk, krn, iterations=5)
res = 255 - cv2.bitwise_and(dlt, msk)
# Displaying chess-board features
res = np.uint8(res)
ret, corners = cv2.findChessboardCorners(res, (7, 7),
flags=cv2.CALIB_CB_ADAPTIVE_THRESH +
cv2.CALIB_CB_FAST_CHECK +
cv2.CALIB_CB_NORMALIZE_IMAGE)
if ret:
print(corners)
fnl = cv2.drawChessboardCorners(img, (7, 7), corners, ret)
cv2.imshow("fnl", fnl)
cv2.waitKey(0)
else:
print("No Checkerboard Found")
To find lower and upper boundaries of the mask, you may find useful: HSV-Threshold-script
Answer from Ahmet on Stack OverflowMy approach for the problem is to perform color-segmentation to get a binary mask. Next, using binary mask to remove the background to make the board visible, removed from artifacts. Finally output the chess border features in an accurate way.
-
- Performing color-segmentation: We convert the loaded image to the HSV format define lower/upper ranges and perform color segmentation using
cv2.inRangeto obtain a binary mask.
- Performing color-segmentation: We convert the loaded image to the HSV format define lower/upper ranges and perform color segmentation using
-
- Extracting chess-board: After obtaining binary mask we will use it to remove the background and separate chess part from the rest of the image using
cv2.bitwise_and. Arithmetic operation and is highly useful for defining roi in hsv colored images.
- Extracting chess-board: After obtaining binary mask we will use it to remove the background and separate chess part from the rest of the image using
-
- Displaying chess-board features. After extracting the chessboard from the image, we will set the
patternSizeto (7, 7) andflagsto adaptive_thresh + fast_check + normalize image inspired from the source.
- Displaying chess-board features. After extracting the chessboard from the image, we will set the
Steps:
Color-segmentation to get the binary mask.

-
lwr = np.array([0, 0, 143]) upr = np.array([179, 61, 252]) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) msk = cv2.inRange(hsv, lwr, upr)
Removing background using mask

-
krn = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 30)) dlt = cv2.dilate(msk, krn, iterations=5) res = 255 - cv2.bitwise_and(dlt, msk)
Displaying Chess-board features

-
res = np.uint8(res) ret, corners = cv2.findChessboardCorners(res, (7, 7), flags=cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE) if ret: print(corners) fnl = cv2.drawChessboardCorners(img, (7, 7), corners, ret) cv2.imshow("fnl", fnl) cv2.waitKey(0) else: print("No Checkerboard Found")
Code:
import cv2
import numpy as np
# Load the image
img = cv2.imread("kFM1C.jpg")
# Color-segmentation to get binary mask
lwr = np.array([0, 0, 143])
upr = np.array([179, 61, 252])
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
msk = cv2.inRange(hsv, lwr, upr)
# Extract chess-board
krn = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 30))
dlt = cv2.dilate(msk, krn, iterations=5)
res = 255 - cv2.bitwise_and(dlt, msk)
# Displaying chess-board features
res = np.uint8(res)
ret, corners = cv2.findChessboardCorners(res, (7, 7),
flags=cv2.CALIB_CB_ADAPTIVE_THRESH +
cv2.CALIB_CB_FAST_CHECK +
cv2.CALIB_CB_NORMALIZE_IMAGE)
if ret:
print(corners)
fnl = cv2.drawChessboardCorners(img, (7, 7), corners, ret)
cv2.imshow("fnl", fnl)
cv2.waitKey(0)
else:
print("No Checkerboard Found")
To find lower and upper boundaries of the mask, you may find useful: HSV-Threshold-script
In my environment (opencv-python 4.7.0.68, opencv 4.5.4), just converting it to grey scale can make it work without additional adjustment (at least detected all but the lower left corners). After downsample by resize(), all corners are detected.
img_captured = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)
# img_captured = cv2.resize(img_captured, (350, 350))
GRID = (7, 7)
found, corners = cv2.findChessboardCorners(
img_captured, GRID, cv2.CALIB_CB_ADAPTIVE_THRESH)
cv2.drawChessboardCorners(img_captured_corners, GRID, corners, found)
cv2.imshow('img_captured_corners', img_captured_corners)
findChessboardCorners no resize
There is also findChessboardCornersSB. From my experience, it works generally better than the plain version. However, I don't know benchmark difference between the two methods.
findChessboardCornersSB
cv2.findChessboardCorners() running endlessly on certain images
image processing - How does OpenCV find chessboard corners? - Signal Processing Stack Exchange
OpenCV (cv2) Python findChessboardCorners failing on seemingly simple chessboard - Stack Overflow
[Question] What is being returned by findChessboardCorners
I was able to obtain a satisfactory result using cv2.goodFeaturesToTrack().
CODE:
corners = cv2.goodFeaturesToTrack(gray_img,25,0.01,10)
corners = np.int0(corners)
for i in corners:
x,y = i.ravel()
cv2.circle(img,(x,y),3,(0,0,255),-1)
cv2.imshow('Corners',img)

I know it is not accurate, but with some pre-processing you should be able to obtain a better result.
:D
This is the best result I can get with the following environment:
- OpenCV 3.2
- chessboard size:
5x5 - image reduced by two in each dimension
- image preprocessed with CLAHE algorithm

C++ code:
cv::Mat img = cv::imread("klpVW.jpg", cv::IMREAD_GRAYSCALE);
cv::resize(img, img, cv::Size(), 0.5, 0.5);
cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();
clahe->apply(img, img);
std::vector<cv::Point2f> corners;
cv::Size boardSize(5, 5);
bool found = cv::findChessboardCorners(img, boardSize, corners);
std::cout << "found=" << found << std::endl;
cv::Mat display(img.size(), CV_8UC3);
cv::cvtColor(img, display, cv::COLOR_GRAY2BGR);
cv::drawChessboardCorners(display, boardSize, cv::Mat(corners), found);
cv::imshow("Chessboard corners", display);
cv::imwrite("test_chessboard_corners.png", display);
cv::waitKey(0);
As your OpenCV version is different, you may not get the same result. Anyway, you should use instead this OpenCV pattern (yours seems slightly different for me) and remember that the calibration pattern must be as flat as possible to get good calibration results.
Hi,
So I’m using opencv and need to find the coordinates of the corners on a chessboard. My current approach is to take the return value of findChessboardCorners, then do math to determine the outer coordinates, then draw circles at each point.
I know there is drawChessboardCorners, but for this project I can’t quite use that. So when I went to draw the circles at the coordinates, I realized that the coordinates returned are not integers. So what exactly are they? I had been assuming they were the coordinates of the corners. I went through documentation and searched around for a while but can’t seem to find anything.
Any help is appreciated, thank you.
Hello guys, I am trying to create a calibration script for a project I am in. Here is the general idea, I will have a reference image with the camera in the correct location. I will find the chessboard corners and save it in a text file. Then, when I calibrate the camera, I will take another image (Ill call it test image) and will get the chessboard corners and save that in a text file. I already have a script that reads in the text file corners and will create a homography matrix and perspective warp the test image to essentially look like the reference image.
I have been struggling to consistently get the chessboard corners function to actually find the corners. I do have some fundamental issues to overcome:
-
There are 4 smaller chessboards in the corner, that all always fixed there.
-
Lighting is not constant.
After cutting the image into quadrants for each chessboard, I have been doing is a mix of image processing techniques. CLAHE, blurring, adaptive filtering for lighting, sobel masks for edge detection as well as some the techniques from this form:
https://stackoverflow.com/questions/66225558/cv2-findchessboardcorners-fails-to-find-corners
I tried different chessboard sizes from 9x6 to 4x3. What are your guys approaches for this matter, so I can get a consistent chessboard corner detection script.
I can only post one image since I am a new user but here is the pipeline of all the image processing techniques. You can see the chessboard rather clearly but the actual function cannot for whatever reason.
diagnostic_pipeline_dot_img_test21920×1280 163 KB
I am writing this debug code in Python but the actual script will run on my Raspberry Pi with C++.