这一部分旨在寻找图像间的对应点和对应区域。并且介绍用于图像匹配的两种局部描述子算法。
2.1 Harris 角点检测器
Harris角点检测算法(也称为Harris&Stephens角点检测器)是一个极为简单的角点检测算法。该算法的主要思想是,如果像素周围显示存在多余一个方向的边,我们认为该点为兴趣点。该点就称为角点。
我们把图像域中点X上的对称半正定矩阵
其中∇I为包含导数Ix和Iy的图像梯度由于该定义,MI的秩为1,特征值为λ1 = |∇I |2和λ2 = 0。现在对于图像的每一个像素,我们可以计算出该矩阵。选择权重为W,我们可以得到卷积:
MI= W ∗MI
该卷积的目的是得到MI在周围像素上的局部平均。计算出的矩阵MI有称为Harris矩阵。W的宽度决定了在像素x周围的感兴趣的区域。像这样在区域附近对矩阵MI,取平均的原因是,特征值会依赖于局部图像特性而变化。如果图像的梯度在该区域变化,那么MI的第二个特征值将不再是0.如果图像的梯度没有变化,MI的特征值也不会变化。
取决于该区域∇I的值,Harris矩阵MI的特征值有三种情况:
- 如果λ1和λ2都是很大的整数,则该点x为角点
- 如果λ1很大,λ2 = 0,则该区域内存在一个边,该区域内的平均MI 的特征值不会变化太大
- 如果λ1=λ2=0,该区域内为空。
在不需要实际计算特征值的情况下,为了把重要的情况和其他情况分开Harris和Stephens引入了只是函数:det(MI ) − κ trace(MI )2.
为了去除加权常数K,我们通常使用商数:det(MI )/trace(MI )2 作为指示器。
下面我们写出harris角点检测程序。对于这个函数,我们需要使用scipy.ndimage.filters模块中的高斯导数滤波器来计算导数。使用高斯滤波器的道理同样是,我们需要在角点检测过程中抑制噪声强度。
首先,将角点响应函数添加到harris.py文件中,该函数使用高斯导数实现。同样地,参数σ定义了使用的高斯滤波器的尺度大小。你也可以修改这个函数,对x和y方向上不同的尺度参数,以及尝试平均操作中的不同尺度,来计算Harris矩阵。
from scipy.ndimage import filters
def compute_harris_response(im,sigma=3):
""" compute the harris corner detector response function
for each pixel in a graylevel iamge."""
#derivatives
imx = zeros(im.shape)
filters.gaussian_filter(im,(sigma,sigma),(0,1),imx)
imy = zeros(im.shape)
filters.gaussian_filter(im,(sigma,sigma),(1,0),imy)
#compute components of the harris matrix
Wxx = filters.guassian_filter(imx*imx,sigma)
Wxy = filters.guassian_filter(imx*imy,sigma)
Wyy = filters.guassian_filter(imy*imy,sigma)
#计算特征值和轨迹
Wdet = Wxx*Wyy - Wxy**2
Wtr = Wxx + Wyy
return Wdet/Wtr
上面的函数会返回像素值为Harris响应函数值的一幅图像。现在,我们需要从这副图想象中挑选出需要的信息。然后选取像素高于却阙值的所有图像点,再加上额外的限制,即角点之间的间隔必须大于设定的最小距离。这种方法会产生很好的检测结果。为了实现该算法,我们获取所有候选像素点,以角点响应的值递减的顺序排序,然后将距离已标记为角点位置过近的区域从候选像素中删除。
def get_harris_points(harrisim,min_dist=10,threhold=0.1):
""" Return corners from a Harris response image min_dist
is the minimum number of pixels separating corners and image
bourndary.
"""
# find top corner candidates above a threshold
corner_threshol