opencv Cv2 findChessboardCorners无法找到角

rjee0c15  于 2023-01-05  发布在  其他
关注(0)|答案(2)|浏览(532)

我在视觉应用程序中使用cv2 findChessBoardCorners进行摄像头校准。我对函数的调用如下所示:

def auto_detect_checkerboard(self, image):
    retval, corners = cv2.findChessboardCorners(image, (7, 7), flags=cv2.CALIB_CB_ADAPTIVE_THRESH
                                                + cv2.CALIB_CB_EXHAUSTIVE)
    if(retval):
        return corners[0][0], corners[0][1]
    else:
        print("No Checkerboard Found")
        assert False

但它似乎无法在我迄今为止尝试过的所有图像上找到任何角落。我使用过的最琐碎的例子是

我使用函数时是否有问题?或者图像是否有问题需要在预处理时处理?
到目前为止,我已经尝试转换到灰度,并应用高斯过滤器,这两种似乎都没有产生影响。

vm0i2vca

vm0i2vca1#

我的方法是先进行颜色分割得到二值化模板,然后利用二值化模板去除背景,使棋盘可见,去除伪影,最后精确输出棋盘边界特征。

  1. 1.**执行颜色分割:**我们将加载的图像转换为HSV格式,定义下/上范围,并使用cv2.inRange执行颜色分割以获得二进制掩码。
  2. 1.**提取棋盘:**在获得二进制掩模之后,我们将使用它来去除背景,并且使用cv2.bitwise_and算术运算将象棋部分与图像的其余部分分离,并且对于定义HSV彩色图像中的ROI非常有用。
  3. 1.显示棋盘特征.在从图像中提取棋盘之后,我们将设置patternSize为(7,7),并且设置flags为adaptive_thresh + fast_check + normalize图像,这是从source得到的启发。
    步骤:
  • 颜色分割得到二值掩码。

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)
  • 使用蒙版去除背景

krn = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 30))
dlt = cv2.dilate(msk, krn, iterations=5)
res = 255 - cv2.bitwise_and(dlt, msk)
  • 显示棋盘特征

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

代码:

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

要查找遮罩的上边界和下边界,您可能会发现以下内容很有用:HSV-Threshold-script

f0ofjuux

f0ofjuux2#

在我的环境(opencv-python 4.7.0.68,opencv 4.5.4)中,只需要将其转换为灰度就可以使其工作,而不需要额外的调整(至少检测到了除左下角以外的所有角)。

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
还有findChessboardCornersSB,从我的经验来看,它一般比普通版本好用,但是我不知道这两种方法之间的基准差异。
findChessboardCornersSB

相关问题