OpenCV(cv2)Python findChessboardCorners在看似简单的棋盘上失败

时间:2017-02-08 17:34:01

标签: python opencv

我有一张从相机拍摄的棋盘图片:

left_image

这是我的最小工作示例代码:

import cv2
print(cv2.__version__)
left_gray = cv2.imread('left_raw.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
print(left_gray.shape)
ret, left_corners  = cv2.findChessboardCorners(left_gray, (6,5))
print(left_corners)

这是输出,表示没有找到任何角落:

2.4.13.1
(1080, 1920)
None

我阅读了其他几个StackOverflow问题:

  1. This question是关于opencv2在一个看似简单的场景中失败的"但是我相信我拥有的图像要简单得多,因为这个图像有一个完全裁剪出来的棋盘版本。在我的情况下,我有一个棋盘,我把它放在一些白色的打印纸上。
  2. This question是关于高分辨率图像的失败。我不确定我使用的相机是否高分辨率,但我的图像与该问题不同,因为这里的棋盘(大致)居中并且没有完全倾斜。
  3. This question是关于"完美"棋盘。然而,那个是对称的,而我的图像不是对称的(它有6行和7列),我使用(5,6)的输入作为我的棋盘。我也试过(6,5),以防我倒退但没有运气。
  4. This question是关于某人弄错了尺码的。用户声称如果我们有一个(10,7)板,则该函数的输入应为(9,7),其中10 =列数,7 =原板中的行数。但是,我认为我们必须从两个维度中减去一个。在任何情况下,我都尝试使用(7,5)和其他一些变体作为我的图像,但没有一个是有用的。
  5. This question是关于MATLAB的,但代码不应该与Python太不相同,并且用户在检测图像时看到了一些成功,即使是比我更复杂的场景。
  6. 我现在有点迷失如何找到角落。有没有人有他们想分享的建议?如果您想测试它们,图像和代码就在这里。我还应该指出,我尝试在拍摄图像时增加原始相机的亮度,但没有运气。

2 个答案:

答案 0 :(得分:3)

我能够使用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)

enter image description here

我知道这不准确,但通过一些预处理,你应该能够获得更好的结果。

:d

答案 1 :(得分:3)

这是我在以下环境中获得的最佳结果:

  • OpenCV 3.2
  • 棋盘大小:5x5
  • 每个维度减少两个图像
  • 使用CLAHE算法预处理的图片

Chessboard corners detection

C ++代码:

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

由于您的OpenCV版本不同,您可能得不到相同的结果。无论如何,你应该使用这个OpenCV pattern(你似乎对我来说略有不同),并记住校准模式必须尽可能平坦,以获得良好的校准结果。