首页 > 其他分享 >基于生长的棋盘格角点检测方法--(1)原理介绍

基于生长的棋盘格角点检测方法--(1)原理介绍

时间:2023-07-11 14:32:37浏览次数:41  
标签:生长 格角点 邻域 角点 -- Corner 棋盘 像素点


前言

棋盘格中角点检测方法是相机标定中必不可少的步骤之一。Opencv中的函数

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

就可以轻松实现棋盘格角点检测结果。如下图所示

基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理


具体使用方法参考如下链接

javascript:void(0)

但是,这种方法虽然简单,但是在实际使用中有如下问题:

1、 需要提前指定棋盘格尺寸。这在很多自动化应用中是很难做到的。

2、 鲁棒性差。棋盘格如果有干扰(比如轻微的遮挡)就会使得检测失败,而且棋盘倾斜角度较大也会检测失败。具体测试见上述链接。

3、 无法处理一张图片包含多张棋盘的情况。

基于此,今天介绍的是一种新的检测方法。主要参考论文《Automatic Camera and Range Sensor Calibration using a single Shot》。可以针对性地解决上述问题。
优点:
1、 不需要提前指定棋盘格数目。
2、 鲁棒性好。因为是基于生长的算法,所以如果出现干扰,就会绕过干扰,生长出最大的棋盘。
3、 可以检测一个图片里包含多张棋盘的情况。
缺点:
1、受棋盘的矩形形状约束,只能生长出矩形的棋盘。严格的说也不能算缺点,因为本身棋盘就是矩形的,真的长出三头六臂还能叫棋盘吗。不过以后我会介绍一种不依赖棋盘约束的方法。
2、计算量较大。主要集中在棋盘生长部分。

先来欣赏一下该方法的结果吧

基于生长的棋盘格角点检测方法--(1)原理介绍_邻域_02

算法原理介绍

算法主要分三个步骤:1、 定位棋盘格角点位置,2、亚像素级角点和方向的精细化,3、优化能量函数、生长棋盘格。下面具体来说明

1、 定位棋盘格角点位置

要处理的图片中一般会包含很多非棋盘的自然或人工背景,所以第一步就是定位角点的位置。下图是角点检测原理示例。

基于生长的棋盘格角点检测方法--(1)原理介绍_邻域_03

首先定义两种不同的角点原型。一种用于和坐标轴平行的角点(上图a),另一种用于旋转45°的角点(上图b)。根据实践经验可以发现,这两种简单的原型对于由透视变换引起的较大范围的变形的角点检测来说,已经足够。每个原型由4个滤波核{A,B,C,D}组成,用于后面和图像进行卷积操作。

下面我们利用这两个角点原型来计算每个像素点与角点的相似程度(Corner likelihood),来看下面的定义:

基于生长的棋盘格角点检测方法--(1)原理介绍_角点检测_04


其中

基于生长的棋盘格角点检测方法--(1)原理介绍_棋盘格生长_05

表示卷积核A和原型i(i=1,2)在某个像素点的卷积响应。

基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理_06

表示原型i的两种可能的flippings,也就是照顾到棋盘格角点可能会出现左对角线为黑,右对角线为白;或者左对角线为白,右对角线为黑的情况,如下图

基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理_07

基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理_08


不难发现如果四个核中有任何一个的响应值比较小的话,Corner likelihood的值c就会很小。这种特点对于去掉大量的非棋盘格式的角点很重要。

对每个像素点都进行上述计算后,得到了一个Corner likelihood图(如上图d)。

我们得到的Corner likelihood图虽然能够给出大致的角点范围,但是如何进一步得到角点精确的位置呢?下一步就是在Corner likelihood图上利用非极大值抑制(non-maxima-suppression,NMS)来获得候选点。
那么何为非极大值抑制呢?
非极大值抑制顾名思义就是抑制不是极大值的元素,搜索局部的极大值。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。这里我们用NMS来选取那些邻域里分数最高的极大值像素点,同时抑制那些分数低的像素点。非极大值抑制算法的详细原理参考:
javascript:void(0)

然后用梯度统计的方法在一个局域的n x n邻域内验证这些候选点(上图e)。先对局域灰度图进行sobel滤波,然后计算加权方向直方图(32bins),用mean shift算法找到其中的两个主要的模态

基于生长的棋盘格角点检测方法--(1)原理介绍_角点检测_09

。根据边缘的方向,对于期望的梯度强度

基于生长的棋盘格角点检测方法--(1)原理介绍_邻域_10

构造一个模板T。

基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理_11

(*表示互相关操作符)和Corner likelihood的乘积作为角点得分(Corner score),然后用阈值进行判断就得到了角点(上图f)。

2、 亚像素级角点和方向的精细化

但是上面得到的角点一般不是很精确,需要进一步对角点的位置以及边缘方向进行亚像素级精细化处理。

假设c是理想的角点位置,p是c的局部邻域的一个像素点,

基于生长的棋盘格角点检测方法--(1)原理介绍_角点_12

是p点的图像梯度向量,那么就有

基于生长的棋盘格角点检测方法--(1)原理介绍_棋盘格生长_13


简单解释一下原因如下图:中心绿色的点表示理想角点c,假如像素点p不在边界上,如下图标号为1的位置,平坦区域梯度

基于生长的棋盘格角点检测方法--(1)原理介绍_角点_14

为零向量,所以

基于生长的棋盘格角点检测方法--(1)原理介绍_邻域_15

;假如像素点p在边界上,如下图标号为2的位置,梯度

基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理_16

向量方向垂直向下,(p-c)方向水平向左,两向量方向互相垂直,所以

基于生长的棋盘格角点检测方法--(1)原理介绍_棋盘格生长_17


基于生长的棋盘格角点检测方法--(1)原理介绍_棋盘格生长_18


上图是理想情况下棋盘格,但是实际上边缘不可能这样锐利(只有一个像素大小),梯度方向也没有这么理想,最理想的角点c的位置就是我们在角点候选点c’的邻域

基于生长的棋盘格角点检测方法--(1)原理介绍_棋盘格生长_19

内找到满足以下式子的c’:

基于生长的棋盘格角点检测方法--(1)原理介绍_角点检测_20


邻域的像素通过梯度幅值自动加权,上述式子右侧对c’求导并令其等于0,可以得到解析解:

基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理_21


下一步就是refine边缘方向矢量e1,e2,可以通过最小化normals的偏差和对应的梯度实现:

基于生长的棋盘格角点检测方法--(1)原理介绍_棋盘格生长_22


基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理_23

3、 优化能量函数生长棋盘格

我们定义棋盘格的能量函数如下:

基于生长的棋盘格角点检测方法--(1)原理介绍_邻域_24


基于生长的棋盘格角点检测方法--(1)原理介绍_算法原理_25


基于生长的棋盘格角点检测方法--(1)原理介绍_棋盘格生长_26


其中第一项E_corners是当前棋盘中角点总数的负值。 第二项E_structure描述了用两个相邻角点来预测第3个角点的匹配程度,分别对棋盘的每行和每列相邻的3个角点(triples)计算其结构能量,取其中的最大值作为该棋盘的结构能量。

值得注意的是,由于结构能量约束中使用的是局域的线性约束,上述棋盘格生长方法可以扩展到鱼眼镜头拍摄的高畸变图像。

基于生长的棋盘格角点检测方法--(1)原理介绍_邻域_27

不难发现,计算量和棋盘大小呈现指数关系,当棋盘尺寸较大时,计算量会非常惊人。所以在求解时不能使用穷举法搜索,在此使用的是一种离散优化策略,在实践中证明比较有效。具体过程(见上图(a))如下:
给定一个种子角点,我们沿着其边缘方向搜索产生一个初始化的种子棋盘格。该棋盘格有3x3个角点,有2x2个棋盘(见上图(a)中最左侧)。然后以此种子棋盘格为基础,分别从最外沿的4个边缘去生长棋盘格,生成4个新的棋盘格proposals。如果其中能量最小的那个棋盘格的能量值比棋盘格扩展前的能量更减少了,就说明生长成功,用这个新的棋盘格代替原来棋盘格。继续生长,直到4个 方向新棋盘格能量不再减少为止。

另外,为了在单张图片中生长出多个棋盘格,我们把每个角点都尝试作为种子点用上述方法去生长,这样会产生多个重叠的棋盘格。我们只保留能量函数最小的那个作为最终的结果,其他的重叠部分去掉即可。

参考资料

1、论文
Geiger A, Moosmann F, Car Ö, et al. Automatic camera and range sensor calibration using a single shot[C]//Robotics and Automation (ICRA), 2012 IEEE International Conference on. IEEE, 2012: 3936-3943.

2、网站
http://www.cvlibs.net/software/libcbdetect/


标签:生长,格角点,邻域,角点,--,Corner,棋盘,像素点
From: https://blog.51cto.com/u_14318213/6688520

相关文章

  • 原来CNN是这样提取图像特征的。。。
    对于即将到来的人工智能时代,作为一个有理想有追求的程序员,不懂深度学习(DeepLearning)这个超热的领域,会不会感觉马上就out了?作为机器学习的一个分支,深度学习同样需要计算机获得强大的学习能力,那么问题来了,我们究竟要计算机学习什么东西?答案当然是图像特征了。将一张图像看做是一个个......
  • 基于生长的棋盘格角点检测方法--(2)代码详解(上)
    上一篇介绍了基于生长的棋盘格角点检测方法的大概原理,详见:基于生长的棋盘格角点检测方法–(1)原理介绍本文进一步从代码解读角度出发,更深入地理解工程中是如何实现的。本文中用到的代码可以从以下链接下载http://www.cvlibs.net/software/libcbdetect/这里我把代码中主要的函......
  • 从零开始一起学习SLAM | 相机成像模型
    上一篇文章《从零开始一起学习SLAM|为啥需要李群与李代数?》以小白和师兄的对话展开,受到了很多读者的好评。本文继续采用对话的方式来学习一下相机成像模型,这个是SLAM中极其重要的内容,必须得掌握哦~小白:师兄,上次听你讲了李群李代数,有种“听君一席话胜读十年书”的赶脚~后来看书感......
  • 基于生长的棋盘格角点检测方法--(3)代码详解(下)
    接着上一篇基于生长的棋盘格角点检测方法–(2)代码详解(上),来看一下第二个重要函数chessboardsFromCorners。该函数的目的是用上一步骤中找到的角点恢复出棋盘结构。首先初始化一个3x3的角点矩阵,也就是一个2x2的棋盘格,这是组成一个棋盘的最小单位了。然后利用定义的棋盘能量函数来从......
  • 浅析synchronized锁升级的原理与实现
    背景在多线程编程中,线程同步是一个关键的概念,它确保了多个线程对共享资源的安全访问。Java中的synchronized关键字是一种常用的线程同步机制,它不仅提供了互斥访问的功能,还具备锁升级的特性。本文将深入探讨synchronized的锁升级原理和实现方式。在jdk1.5(包含)版本之前,因为加锁和......
  • Python: Yield & With/As
    Howtouseyield:https://www.runoob.com/w3cnote/python-yield-used-analysis.htmlHowtousewith/ashttps://www.jianshu.com/p/c00df845323c......
  • 常用Dos命令
    常用Dos命令打开方式windows键+R(打开cmd的推荐方式)盘符切换C:D:查看当前目录下的所有文件dir切换目录cd同级目录进入下一级目录cd..返回上一级目录通过“cd/d地址”可以访问任意地址清理屏幕cls退出终端exit查看电脑ipipconfig打开应用略ping命令ping+......
  • 表格分页多选默认回显实现
    element的表格可以使用row-key和reserve-selection来实现多选翻页回显,但是在使用过程中却出现了,翻页之后,翻页保存的数据丢失问题。复现前准备首先是使用el-table和el-pagination搭建好基本的页面,包括获取表格数据事件,翻页事件以及表格的selection-change、row-key、re......
  • js 检测文本是否溢出
    自定义指令的方式手写实现/***检测文本是否溢出*参考https://github.com/ElemeFE/element/blob/dev/packages/table/src/table-body.js#L241*@param{*}e*@returns*/functionisEllipsis(e){returnnewPromise(resolve=>{constel=window.event......
  • AT_abc306_h 题解
    AT_abc306_hBalanceScale题解Links洛谷AtCoderDescription有\(N\)个编号为\(1,2,\dots,N\)的砝码。有\(M\)次比较操作,每次比较砝码\(A_{i}\)和\(B_{i}\),\(A_{i}\)在左侧。分为三种情况:左边的砝码更重。右边的砝码更重。两边的砝码重量相同。将每次比较的......