类神经网络的角点检测方法

今天阅读了一篇论文里面提到一种类神经网络模型Connectionist Model的角点检测方法,非常有意思,虽然说这篇论文里面介绍的方法结构特征复杂(图像的每个点都需要一对神经元的表示),而且只能针对于结构简单二值或灰度图像,但这个方法非常有启发性。

如今提到角点检测,大概不外乎两种思路。第一种方法就是通过一阶或二阶梯度,获得局部角程度描述,包括了Harris算子等,这种思路最容易理解,研究也多,应用也广泛,效果也比较出色。第二种方法就是从边缘曲线出发,找到边缘曲度变化最大的地方,这种方法需要依赖于边缘曲线提取精度,所以非常不稳定。

我所读的这篇文章利用神经网络的方法也并不稀奇,早在90年代初,就有人用过这样的方法,不过一般都是先建立一系列的角点模板,然后通过神经网络去匹配,计算量较大,而效果也并不突出(主要是由于角点出现的可能情况,远比人工建立的模板多)


JayantaBasak这篇文章的思路就是有这么几点:

(1)图像的尺度越粗糙(被平滑后,或放大),角点的角程度就越不明显(实际上表现为你在较大尺度上看物体,一些角点会看不到),反之图像尺度越精细,会带来更多细小角点,而这个尺度粗细描述也可以角点的视察邻域的大小变化。

(2)在小邻域里面,角点周围的点也会受到角点影响,带有一定的角程度,而角点拥有局部最大值。


(3)角点的角程度用一个角度向量表示,角度向量是由角点与其邻域上边界点向量的和,将其分解为x,y方向上的两个标量,分别各作为一组神经网络的输入


(4)对于M*N大小图像共有2M*2N个神经元,每个像素点都有一对神经元,分别表示其角度向量的x,y分量,这两个分量的神经元没有互连,每个神经元同其邻域的点都相连,每个神经元另外还有一个自我负反馈(为了排除噪声的影响)


下面正题——大概的算法思路

(1)角度向量的初始化:找到点其3*3邻域的两个边界点(论文里用的主要是二值图,这里的边缘点实际上指像素不为0点),计算其角度向量,其x,y分量分别作为两组神经网络的输入,两者都没有互连。


(2)之后,经由神经网络自学习过程,不用再进行额外的输入了,以下是神经元的自我更新公式:





这里的j是当前神经元,i是属于其邻域N(j)的神经元,wij是神经元之间的连接权值,cxi是神经元i给j的输入(这里是个斜坡函数,也可以理解为经过一个激活函数),uj是指神经元j的当前时间的输出,其关于时间的t的变化等于其邻域神经元的输入权值和减去自身反馈。(这里可能有点难以理解,直观的讲,一是其邻域的角度正反馈会提高当前点的角程度,二是如果没有周围邻域的角度正反馈,自身的负反馈会减少自身从而达到排除噪声的目的,因为噪声一般都是孤立的。这里可以结合思路(2)里好好想想)



神经元的连接权值实际上是与邻域的半径有关的,我们先前已经知道了,思路(1)里说图像的尺度越粗糙,角点的角程度就越不明显,这时需要较大权值,而随着尺度越精细,角程度就越明显,权值也在变小。那么问题就是为什么我们需要让邻域的半径随着时间缩小呢?因为在大的尺度下,我们可以排除小的毛刺角点影响(被尺度平滑了),而随着尺度的缩小,我们又可以进一步精化角点位置,这好像又是另一种多尺度的思想了。

(3)收敛性考虑,当r<1.5时,那么停止,此时可以得到每个点的最终角向量值,找到局部最大值即为角点,这里还需要设置一个阈值,把小的局部点变化排除。对于给定的半径r,神经网络整体能量:

 

其关于时间变化的导数如下,可以分析出,它是随时间变化,慢慢接近于0的:


参考文献:

A Connectionist Model for Corner Detectionin Binary and Gray Images

import cv2 as cv import numpy as np """"" cv2.cornerHarris() 可以用来进行角点检测。参数如下: • img - 数据类型为 float32 的输入图像。 • blockSize - 角点检测中要考虑的领域大小。 • ksize - Sobel 求导中使用的窗口大小 • k - Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06] """"" src_inital = cv.imread("E:/opencv/picture/building.jpg") src = cv.cvtColor(src_inital,cv.COLOR_BGR2GRAY) src = np.float32(src) dst = cv.cornerHarris(src,3,3,0.04) #R值是由det(M)-K(trace(M))*(trace(M)),当该点是角点时,该点所对应的R值就会很大,通过设置对R的阈值,就可以筛选得到角点 #这里的dst就是R值构成的灰度图像,灰度图像坐标会与原图像对应,R值就是角点分数,当R值很大的时候 就可以认为这个点是一个角点 print(dst.shape) src_inital[dst>0.08*dst.max()]=[0,0,255] """"" src_inital[dst>0.08*dst.max()]=[0,0,255] 这句话来分析一下 dst>0.08*dst.max()这么多返回是满足条件的dst索引值,根据索引值来设置这个点的颜色 这里是设定一个阈值 当大于这个阈值分数的都可以判定为角点 dst其实就是一个个角度分数R组成的,当λ1和λ2都很大,R 也很大,(λ1和λ2中的最小值都大于阈值)说明这个区域是角点。 那么这里为什么要大于0.08×dst.max()呢 注意了这里R是一个很大的值,我们选取里面最大的R,然后只要dst里面的值大于百分之八的R的最大值  那么此时这个dst的R值也是很大的 可以判定他为角点,也不一定要0.08可以根据图像自己选取不过如果太小的话 可能会多圈出几个不同的角点 """"" cv.imshow("inital_window",src_inital) cv.waitKey(0) cv.destroyAllWindows() 目标: 理解Harris角点检测的概念 使用函数cv2.cornerHarris(),cv2.cornerSubPix() 原理: Harris 角点检测方法大概原理就是建立一个窗口区域,然后以当前窗口为中心向各个方向进行偏移。 如上图所示,第一个窗口向各个方向偏移的时候,像素值没有变化,因为窗口偏移的时候没有遇到任何边缘信息。 第二个图,窗口当中有一个直线(即block是在边缘上),如果当前窗口进行上下的移动,也没有像素值发生变化(在其他方向上灰度值也会变化)。 第三个图,窗口覆盖了一个“拐角”,如果窗口进行偏移,任何方向上都会有像素变化。 所以,第三张图片判断为检测到角点。 判断特征点是否为角点的依据:R只与M值有关,R为大数值正数时特征点为角点,R为大数值负数时为边缘,R为小数值时为平坦区 寻找R位于一定阈值之上的局部最大值,去除伪角点。 方向导数IxIx和IyIy可以使用cv2.Sobel()函数得到 Harris角点检测的结果是灰度图,图中的值为角点检测的打分值。需要选取合适的阈值对结果进行二值化来检测角点。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值