Wlgls 冲鸭!

第三节:计算机视觉--角点检测

2019-10-09

Harris角点检测

理论

在图像中,角是各个方向强度变化很大的区域。

为了得到特征点,我们引入了局部窗口W。如果窗口W向任意方向的移动都导致图像灰度的明显变化,就意味着这是一个特征点。

2019-10-17-14-06-19.png

我们将窗口W平移(u, v), 那么我们可以得到窗口W内的所有像素的变化,也就是

2019-10-17-14-06-33.png

显然,E(u, v)越大,说明在(u, v)方向变化越大。

在图片中的移动可以简略为八个方向[(1, 0) (-1,0) (0, 1) (0,-1) (1, 1), (-1, -1)(1, -1) (-1, 1)](45度一个方向, 上下左右,加上两个对角线四个方向),然后我们可以得到得到八个方向上的E值,只要其中最小的E值仍然比较大,就意味着这是一个角度。

但是八个方向还是不够精确,我们通过泰勒公式(具体推倒见书)将上式展开就可以得到,一个更为简便的表示方式:

2019-10-17-14-07-05.png

事实上,我们可以把E(u, v)的二次型函数想象成一个椭圆,其中两个轴的大小是矩阵H的两个特征值λ1和λ2。 而对应的x1和x2两个特征向量就是变化的方向(这个理论来自二次型矩阵,有空去看一下线性代数的二次型矩阵)。

2019-10-17-14-07-24.png

然后我们可以通过矩阵H得到特征值与对应的特征向量(线性代数好重要啊)。

不妨,现在有λmax和λmin两个特征值,Xmax和Xmin两个特征向量。如椭圆所示。

  • Xmax是E值增幅最快的方向, λmax是Xmax方向上增大的幅值

  • Xmin是E值增幅最小的方向, λmim是Xmin方向上增大的幅度 (也就是说在这个方向上,(u,v)的改变在使得E值变化不大)

(我一直无法理解,这到底是为什么,我仅阐述一下个人的看法)

大概是在Xmin方向,比如(0, 0)->(u,v)的一个变化,使得E值很小,这也就是像素的变化很小。

在前面已经给出,角点就是各个方向上都变化比较快的地方,所以,当λmin值也很大时,就说明该角点是各个方向上变化最快的地方。如图:

2019-10-17-14-08-51.png

我们还有其他几种harris算子, 这比λmin更有效一些

2019-10-17-14-09-39.png

2019-10-17-14-09-44.png

改进

由于存在噪声的原因,我们单纯的根据上式计算H矩阵效果不佳,将w窗口设置为一个高斯核,然后与H矩阵进行一次卷积。会得到更好的效果

2019-10-17-14-09-57.png

最后H矩阵就会成为变为

2019-10-17-14-10-04.png

也就是说(实际上就是一个高斯卷积):

2019-10-17-14-10-15.png

2019-10-17-14-10-20.png

2019-10-17-14-10-28.png

Harris角点特征不变性

特征不变形一般包括两个方面,不变性协变性, 一般不变性和协变性统称为不变性

不变性是指:图像变换后,角点位置不变

协变性是指: 如果两张同一图像的变换版本,则在相应的位置检测到相同特证

Harris角点的不变性

Harris角点检测对于平移变换和旋转变换和仿射强度是具有不变性的。

  1. 图像平移

    首先,Harris角点检测由于是使用了一个窗口W进行检测, 所以哪怕图像平移了,对于特定的角点是不影响的

    2019-10-10-19-25-01

    所以角点位置对平移变换是协变的

  2. 图像旋转

    在计算Harris角点时,我们将计算公式等价为了一个椭圆,一个图像旋转了,但是某一个角点的椭圆跟着旋转但其特征值没有发生变化, (特征向量发生了变化)。

    2019-10-10-19-30-25

    角点位置对旋转变换是协变的。

  3. 放射强度变换

    即使我们给一个图片增加了强度,但是由于我们在进行harris角点检测的时候使用的是微分运算,而微分运算对亮度的抬高和下降并不敏感。所以对亮度和对比度的仿射变换不改变harris相应的极值点出现的位置。但是会影响角点检测的数量。

    2019-10-10-19-41-23

  4. 尺度变换

    Harris角点检测对于尺度变换不具有不变性, 如图

    2019-10-10-19-42-32

    如果将一个角点放大,则会被检测为多个边缘而不是角点

    为此,似乎有一个多尺度Harris角点检测,有空可以去看

实现步骤

  1. 先进行高斯滤波(可不做)
  2. 使用Sobel算子为每一个像素点求出Ix和Iy矩阵
  3. 为每一个像素点计算IxIx, IyIy, Ix*Iy。
  4. 为上一步中生成的三个矩阵进行高斯卷积, (需要注意的是,进行高斯卷积之后,矩阵中就已经存储的是A,B,C的值了。)
  5. 为每一个像素点生成矩阵H
  6. 然后选定特定的Harris算子求值, 并进行阈值处理 比如如果使用经典的Harris算子, 那么R=det(M)-αTrace(H)²=λ1λ2 - α(λ1+λ2)², 又因为特征值之积等于矩阵的行列式,特征值之和等于矩阵的对角线之和。所以R=AB-C² - α(A+B)²
  7. 寻找局部最大点。

Opencv实现

cv.cornerharris()是Opencv提供用于Harris角点检测的函数

Opencv提供的函数所使用的Harris算子是

2019-10-17-14-10-55.png

dst = cv.cornerHarris(src, blockSize, ksize, k, borderType)

参数:

  • src: 原图像
  • dst: 存储harris角点的R值,他的类型是CV_32FC1, 尺寸与图像相同。
  • blockSize: 窗口大小
  • ksize: Sobel算子的尺寸,一般为3
  • k: alpha值, 一般为0.04~0.06
  • borderType: 像素外推法

一般我们还会手动进行一次阈值处理来获得更为准确的角点(可选)