一.角点检测器
什么是角点?在任意方向的一个微小变动都会引起灰度很大变化的点
- 角点是一阶导数(即灰度的梯度)的局部最大所对应的像素点;
- 角点是两条及两条以上边缘的交点;
- 角点指示了物体边缘变化不连续的方向;
- 角点处的一阶导数最大,二阶导数为0;
- 角点是指图像中梯度值和梯度方向的变化速率都很高的点。
目前的角点检测算法可以归结为以下三类
基于灰度图的角点检测
基于二值图的角点检测
基于轮廓曲线的角点检测
基于灰度图的角点检测又可以分为基于梯度、基于模板和基于模板梯度组合的三类方法。
其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点,Harris角点检测算法就是基于模板的角点检测方法。
代码
# -*- coding:utf-8 -*-
from PIL import Image
from numpy import *
from pylab import *
from scipy.ndimage import filters
def compute_harris_response(im, sigma=3):
""" 在一幅灰度图像中,对每一个像素计算Harris角点检测器响应函数
im:(数组图像) sigma=3:标准差为3
"""
#计算x方向的导数
imx = zeros(im.shape) #zeros()生成全零数组
filters.gaussian_filter(im, (sigma,sigma),(0,1),imx)
#计算x方向的导数
imy = zeros(im.shape) #zeros()生成全零数组
filters.gaussian_filter(im, (sigma,sigma),(0,1),imy)
#计算harris矩阵的分量
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
#获取角点
def get_harris_points(harrism, min_dist=10, threshold=0.1):
"""从一幅Harris响应图像中返回角点。min_dist为分割角点和图像边界的最少像素数目"""
#寻找高于阈值的候选角点
corner_threshold = harrism.max()*threshold
harrisim_t = (harrisim > corner_threshold) * 1
#得到候选点的坐标
coords = array(harrisim_t.nonzero()).T
#以及它们的Harris响应值
candidate_values = [harrism[c[0],c[1]] for c in coords]
#对侯选点按照Harris响应值进行排序
index = argsort(candidate_values)
#将可行点的位置保存到数组中
allowed_locations = zeros(harrism.shape)
allowed_locations[min_dist:-min_dist,min_dist:-min_dist]=1
#按照min_distance 原则,选择最佳Harris点
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
def plot_harris_points(image, filtered_coords):
"""绘制图像中检测到的角点"""
figure()
gray()
imshow(image)
plot([p[1] for p in filtered_coords],[p[0] for p in filtered_coords], '*')
axis('off')
show()
if __name__ == "__main__":
im = array(Image.open("/Users/apple/Desktop/集大.jpeg").convert("L"))
harrisim = compute_harris_response(im)
filtered_coords = get_harris_points(harrisim,6)
plot_harris_points(im, filtered_coords)