Harris 角点检测算法
1. 角点
角点是水平方向、垂直方向变化都很大的像素。
2. 流程
(1)找出角点
用高斯算子求出像素水平方向和垂直方向的梯度dx, dy,–> 对梯度的平方dxdx ,dydy, dxdy滤波得到Wxx ,Wxy,Wyy --> 在求的(WxxWyy - Wxy**2)/(Wxx + Wyy)作为候选角点。
(2)筛选角点
根据阈值筛选角点–> 取得角点的坐标 -->根据角点坐标得到角点所在的行 --> 在角点周围,删除掉其他角点。–> result
(3)标记角点
3. 实现
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import filters
## 1.找出角点
### 1.1 步骤:img求导 --> imx ,imy 滤波-->Wxx ,Wxy,Wyy --> (Wxx*Wyy - Wxy**2)/(Wxx + Wyy)
def compute_harris_response(img,sigma=3):
# 求梯度
imgx,imgy = np.zeros(img.shape),np.zeros(img.shape)
filters.gaussian_filter(img,(sigma,sigma),(0,1),imgx)
filters.gaussian_filter(img,(sigma,sigma),(1,0),imgy) # [260,263]
# 对梯度进行高斯滤波
wxx = filters.gaussian_filter(imgx**2,sigma)
wyy = filters.gaussian_filter(imgy**2,sigma) # [260,263]
wxy = filters.gaussian_filter(imgx*imgy,sigma)# [260,263]
## 求行列式和迹
wdet = wxx*wyy -wxy**2
wtr = wxx + wyy
return wdet/wtr
## 2 筛选角点
### 2.1 步骤:根据阈值筛选角点--> 取得角点的坐标 -->根据角点坐标得到角点所在的行 -->
# --> 在角点周围,删除掉其他角点
def get_harris_points(harri,min_dist=4,threshold=0.1):
corner_thre = harri.max()*threshold # 角点阈值
mask = (harri > corner_thre)*1 # 取出大于阈值的点为候选角点
cords = np.array(mask.nonzero()).T # 取候选角点的坐标
values = [harri[i[0],i[1]] for i in cords] # 候选角点的值
cls = np.argsort(values) # 对角点排序得到排序后的序列号,序列号也是候选角点所在的行
loc = np.zeros(harri.shape) # 划出可行性区域
loc[min_dist:-min_dist,min_dist:-min_dist] = 1
re_cords = []
for i in cls: # 筛选角点。先取出角点,角点周围的点不再取出
if loc[cords[i,0],cords[i,1]] == 1 :
re_cords.append(cords[i])
loc[cords[i,0]-min_dist:cords[i,0]+min_dist,cords[i,1]-min_dist:cords[i,1]+min_dist]=0
return re_cords
def plot_harri(img,cords):
plt.figure()
plt.gray()
plt.imshow(img)
plt.plot([i[1] for i in cords],[i[0] for i in cords],'.')
plt.axis('off')
plt.show()
## 3 测试
if __name__ == '__main__':
img = np.array(Image.open('luna.png').convert('L'))
harri = compute_harris_response(img)
re_cords = get_harris_points(harri)
plot_harri(img,re_cords)
http://en.wikipedia.org/wiki/Corner_detection