在opencv中查找任何随机ChessBoard的CheckerBoard点(模式大小未知)

alc*_*t95 7 c++ opencv image-processing computer-vision opencv3.0

好吧,OpenCv在C++中附带了它的函数findCheckerboardCorners()

bool findChessboardCorners(InputArray image, Size patternSize, 
OutputArray corners, 
int flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE )
Run Code Online (Sandbox Code Playgroud)

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

Fra*_*ari 12

简短的回答:你做不到.

OpenCV棋盘检测代码假定图案是均匀的(所有正方形具有相同的尺寸),因此,为了唯一地定位其在图像中的位置,必须达到两个条件:

  1. 图案必须完全可见.
  2. 模式必须具有已知的行数和列数.

如果违反了1或2,则无法知道哪个角落是"左上角".

对于更一般的情况,特别是如果您预期模式可能被部分遮挡,则必须使用不同的算法和非均匀模式,可以在其上唯一地标识角.

有各种方法可以做到这一点.我最喜欢的模式是Matsunaga和Kanatani的"2D条形码",它使用具有独特交叉的方形长度序列.请参阅此处的论文.为了匹配它,一旦您将角分类到网格中,您可以使用简单的多数投票算法:

  • 在水平和垂直方向上预先计算所有图案的连续4元组角的交叉.
  • 对网格中检测到的角点执行上述操作.
  • 对于每个可能的水平移位
    • 在每一行
      • 累计在阈值内达成一致的交叉数量
  • 选择协议数量最多的水平班次.
  • 对每个可能的垂直位移重复上述步骤,计算沿列的交叉排序.

将检测到的角放置在网格中可以以各种方式实现.有一种经常重新发现的算法使用拓扑邻近.我们的想法是首先将每个角落与其小窗口内的所有正方形相关联,从而构建一个角落 - 正方形表格,然后将其作为图形遍历,以构建每个角落彼此偏移的全局表格.