在 opencv 中为任何随机棋盘查找棋盘点(模式大小未知)

Finding CheckerBoard Points in opencv for any random ChessBoard( pattern size not known)

好吧,OpenCv 在 C++ 中带有它的函数 findCheckerboardCorners(),就像

bool findChessboardCorners(InputArray image, Size patternSize, 
OutputArray corners, 
int flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE )

使用这个功能一段时间后,我了解到的一件事是图案大小必须在很大程度上符合图像,否则算法将拒绝检测任何棋盘。我想知道是否有任何棋盘的随机图像,这个函数会失败,因为输入 patternSize 的精确值是不切实际的。有没有办法,这个函数的 patternSize 可以从提供的图像中获得。任何帮助,将不胜感激。谢谢

findChessboardCorners 的文档说

patternSize – Number of inner corners per a chessboard row and column

所以patternSize不是图片里面棋盘的大小而是内角的个数。内角的数量与图像内部棋盘的大小无关。

例如下图https://github.com/Itseez/opencv/blob/3.1.0/samples/data/chessboard.png patternSize 应该是 cv::Size(7,7).

简答:不能。

OpenCV的棋盘格检测代码假定图案是统一的(所有方块的大小都相同),因此,为了唯一定位其在图像中的位置,必须满足以下两个条件:

  1. 图案完全可见。
  2. 该模式的行数和列数已知。

如果违反了 1 或 2,则无法知道哪个角是 "top left" 角。

对于更一般的情况,特别是如果您预计图案可能会被部分遮挡,则必须使用不同的算法和非均匀图案,这样角点就可以被唯一识别。

有多种方法可以做到这一点。我最喜欢的图案是 Matsunaga 和 Kanatani 的“二维条形码”,它使用具有独特交叉比的方形长度序列。请参阅论文 here。为了匹配它,一旦你把角排序成一个网格,你可以使用简单的多数表决算法:

  • 预先计算所有图案的角的连续 4 元组在水平和垂直方向上的交比。
  • 对网格中检测到的角执行上述操作。
  • 对于每一个可能的水平移动
    • 每一行
      • 累积在阈值内一致的交叉比率数
  • Select同意数最多的水平移动。
  • 对每个可能的垂直位移重复上述操作,计算各列的交叉比率。

可以通过多种方式将检测到的角点放置在网格中。有一个经常被重新发现的 algorithm 使用拓扑邻近性。思路是首先将每个角与它的一个小window范围内的所有正方形相关联,从而构建一个角->正方形table,然后将其作为图遍历以构建全局table 每个角的偏移量。