【问题标题】:OpenCV (cv2) Python findChessboardCorners failing on seemingly simple chessboardOpenCV(cv2)Python findChessboardCorners 在看似简单的棋盘上失败
【发布时间】:2017-02-08 17:34:01
【问题描述】:

我有以下从相机拍摄的棋盘图像:

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

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 = 原始板中的行数。但是,我认为我们必须从 both 维度中减去一个。在任何情况下,我都尝试使用 (7,5) 和其他一些变体来制作我的图像,但没有一种情况有效。
  5. This question 是关于 MATLAB 的,但代码与 Python 应该没有太大的不同,并且该用户在检测图像方面取得了一些成功,即使是在比我所拥有的复杂得多的情况下。

在这一点上,我对如何找到角落有点迷茫。有没有人想分享一些建议?如果您想测试它们,图像和代码就在这里。我还应该指出,我在拍摄图像时尝试增加原始相机的亮度但没有运气。

【问题讨论】:

  • 试试cv2.goodFeaturesToTrack()怎么样?
  • 这是最好的结果 (imgur.com/a/y2FyF) 我可以使用5x5 网格并将图像大小减小两倍。如果您可以拍摄新图像,我建议您使用官方 OpenCV 棋盘 (raw.githubusercontent.com/opencv/opencv/master/doc/pattern.png),因为您的对我来说似乎略有不同。另请记住,要获得良好的校准,校准图案必须尽可能平坦(校准方法依赖于平坦的校准图案)。

标签: python opencv


【解决方案1】:

我使用cv2.goodFeaturesToTrack()获得了满意的结果。

代码:

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)

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

:D

【讨论】:

  • 是的,也许我应该继续使用它...这样做的唯一原因是我需要相机校准中的点,并且我需要在左右图像上匹配点。因此,如果它只是角落的一个子集,那很好,但我将不得不手动检查相机是否检测到左/右图像中的相同角落。
  • 说得好。只需确保您的图像/视频提要能够准确标记角落
  • 看看THIS PAGE 以及:D
  • 我认为问题更多在于原始棋盘的整体质量,看起来像是有人坐在上面然后靠墙擦了一会儿。一堆角落里有白点,等等。据我回忆,你希望棋盘质量好,绝对平整。 |也许也抛弃 JPEG(有损压缩,添加人工制品)。 |该图像中似乎有一些严重的渐晕......
  • 好点。我认为质量可能是个问题。无论如何,我现在已经用这个新棋盘解决了这个问题,所以我不需要 goodFeatures 部分,但感谢您让我知道。
【解决方案2】:

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

  • OpenCV 3.2
  • 棋盘大小:5x5
  • 图像在每个维度上缩小了两个
  • CLAHE算法预处理的图像

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(你的对我来说似乎略有不同),并记住校准模式必须尽可能平坦才能获得良好的校准结果。

【讨论】:

  • 感谢您的回答。我同意我应该更新并获得更好的图像。 (问题是我是在我不拥有的共享计算机上执行此操作的,但我会向维护人员提出这个问题。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-26
  • 2018-05-20
  • 2013-05-17
  • 1970-01-01
  • 2014-12-01
  • 2020-05-04
  • 1970-01-01
相关资源
最近更新 更多