一、Harris角点检测算法
1.什么是角点
下面有两幅不同视角的图像,通过找出对应的角点进行匹配
我们可以直观的概括下角点所具有的特征:
轮廓之间的交点;
对于同一场景,即使视角发生变化,通常具备稳定性质的特征;
该点附近区域的像素点无论在梯度方向上还是其梯度幅值上有着较大变化;
2. 角点检测算法基本思想是什么?
移动窗口W,位移为(u,v),比较移动前后的像素变化
其中窗口函数可以是平坦的,也可以是高斯的如下图:
首先,将图像窗口平移[u,v]产生灰度变化的自相关函数如下:
经过一系列E(u,v)表达式的演化, E(u,v)表达式可以更新为:
其中矩阵M是2x2矩阵,可由图像的导数求得:
3.角点响应函数R
其中k是常量,一般取值为0.04~0.06,这个参数仅仅是这个函数的一个系数,它的存在只是调节函数的形状而已。
4. 用python实现Harris角点检测
(1)Harris角点检测器的响应函数
Harris角点检测器的响应函数会返回像素值为 Harris 响应函数值的一幅图像。
from PIL import Image
from numpy import *
from pylab import *
from scipy.ndimage import filters
def compute_harris_response(im,sigma=3): #在灰度图像中计算每个像素的Harris的焦点响应函数
# 计算导数
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)
#矩阵分量
Wxx = filters.gaussian_filter(imx*imx,sigma)
Wxy = filters.gaussian_filter(imx*imy,sigma)
Wyy = filters.gaussian_filter(imy*imy,sigma)
#特征值
Wdet = Wxx*Wyy - Wxy**2
Wtr = Wxx + Wyy
return Wdet/Wtr
(2)返回Harris角点函数
def get_harris_points(harrisim,min_dist=10,threshold=0.5):
#挑选高于阈值
corner_threshold = threshold
harrisim_t = (harrisim > corner_threshold) * 1
#得到坐标
coords = array(harrisim_t.nonzero()).T
#响应值
candidate_values = [harrisim[c[0],c[1]] for c in coords]
#按照响应值排序
index = argsort(candidate_values)[::-1]
#将可行点的位置存放于数组
allowed_locations = zeros(harrisim.shape)
allowed_locations[min_dist:-min_dist,min_dist:-min_dist] = 1
#选择最佳的角点
filtered_coords = []
for i in index:
if allowed_locations[coords[i,0],coords[i,1]] == 1:
filtered_coords.append(coords[i])
allowed_locations[(coords[i,0]-min_dist):(coords[i,0]+min_dist),(coords[i,1]-min_dist):(coords[i,1]+min_dist)] = 0
return filtered_coords
(3)可视化
def plot_harris_points(image,filtered_coords):
#可视化
figure(dpi = 120)
gray()
imshow(image)
plot([p[1] for p in filtered_coords],
[p[0] for p in filtered_coords],'*')
axis('off')
show()
(4)Harris角点检测实例
from pylab import *
from PIL import Image
#读入图像
im = array(Image.open('data/test/no/jmu1.jpg').convert('L'))
#检测harris响应函数
harrisim = compute_harris_response(im)
#Harris响应函数
harrisiml = 255 - harrisim
figure(dpi = 150)
gray()
#画出响应图
subplot(221)
imshow