黑白棋盘的角点匹配

本文介绍了一种使用OpenCV解决棋盘角点匹配问题的方法。通过最小外接矩形和逐行扫描的策略,实现了自动匹配棋盘角点,避免了手动操作并解决了因棋盘旋转和倾斜导致的匹配困难。算法包括获取棋盘角点、构造射线并逐步搜索匹配点,最终得到对应关系。
摘要由CSDN通过智能技术生成

转载请注明出处:http://my.csdn.net/ye_shen_wei_mian

前段时间碰到了一个有点奇怪但是也挺有趣的问题,就是对棋盘进行双目的特征点匹配的问题。(其实本来只是想拿个棋盘来测距一下的,谁知道碰上了这么一个问题)

对于这个问题,当然你可以说,我手动点击左右两幅图片中两个匹配的棋盘角点让他们对应起来不就完了吗?是的,确实是这样,但是手动点击的位置准不准确呢?能否实现算法的自动匹配呢?或许感觉看起来研究这个问题有点闲着蛋疼,但是。。。确实有点闲着蛋疼,但既然闲着蛋疼了就不妨研究研究棋盘到底要怎么进行特征点对应。

在OpenCV的应用中,Sift、Surf、Fast等特征算子进行特征点检测,再使用BruteForceMatcher或者是FlannBasedMatcher进行匹配,然后经过一系列的错误匹配去除步骤获取优质匹配,几乎是2D-2D的特征点匹配的常规做法。

但是本人实验发现,由于(国际象棋)棋盘的pattern太过类似,在匹配的时候,会出现大量错误的匹配,使用针对Sift或者Surf匹配行之有效的错误点去除算法在这里效果反倒是非常不好,棋盘角点几乎就没有对应起来,那怎么办呢?

还原一下问题,棋盘中最显著的特征无疑是棋盘的角点了,而OpenCV中的findChessboardCorners()函数+cornerSubPix()函数的配合使用已经能为我们获取棋盘角点的亚像素精度的位置信息了。

vector<Point2f> corners;

findChessboardCorners(gray,Size(7,7),corners,CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);

cornerSubPix( gray, corners, winSize, zeroZone, criteria );

现在的问题仅仅是如何将它们一一对应起来,这样其实就完成了匹配了。然而观察上述两个函数返回的角点信息,发现棋输出的棋盘角点位置信息因棋盘在图片中的旋转和倾斜角度位置不同,其输出的顺序也是不同的。比如说同时拍摄同一个棋盘的左右两幅图片中,左图的棋盘角点就按照图片先width后height的规律输出到corners这个vector里,而右图的则是大致从左到右从上到下。这就带来一个问题了,我们不能够把左图获取的corners[i]与右图获取的corners[i]简单的匹配起来就完事了,因为这根本就不是对应点。

既然如此,有没有别的方法可以不手动操作又让它们准确的对应(匹配)起来呢?经过之前粗略的涉猎过的raycasting的射线的启发,遂提出一种使用逐行扫描的方式进行棋盘角点匹配(对应)的方法。

算法大致思路:

1、利用OpenCV中的最小外接Rect的方法,通过搜寻与其左上角与右上角最近的点,获取现有的棋盘角点集合的左上角与右上角的两个点。如果把棋盘的角点从上到下从左到右地划分,这样其实就获取了棋盘第一行的两个端点。

2、将这两个端点构造一条射线,具体地就是计算左上角点到右上角点的方向矢量作为射线方向,然后逐步地步进,在每一步步进都计算与剩余棋盘角点点集的点的距离:

如果发现剩余棋盘角点点集中某一棋盘点与当前处于的位置小于某个阈值,则将该点列为这条射线经过的一个点,将其push_back到新的vector里,同时将这个点从剩余棋盘角点点集中去除,然后继续进行下一次的步进。

否则继续下一步的步进。

直到达到该行的应该有的最大的角点个数,那么这一行的步进完成。

3、其余各行也是相同的步骤。但因为这里采用的是 最小外接Rect+剩余棋盘角点点集 相结合的方法,其实只需要迭代棋盘的行数,比如7*7的棋盘那就是7行,就可以完成操作了。

事不宜迟还是上代码吧。

sort_chessboardcorners.h

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值