Harris角点检测——python实现

文章目录

  • 一.Harris角点检测
  • 1.实验原理
    • 1.1什么是角点
    • 1.2数学表达
  • 2.实验代码
  • 3.实验结果及分析
  • 3.1边缘多的场景
    • 3.1.1正面亮
    • 3.1.2正面暗
    • 3.1.3正面远
    • 3.1.4旋转
    • 3.1.5 侧面
    • 3.1.6结论
  • 3.2角点丰富的场景
    • 3.2.1正面近
    • 3.2.2正面亮
    • 3.2.3正面暗
    • 3.2.4旋转
    • 3.2.5侧面
    • 3.2.6结论
  • 3.3纹理平坦的场景
    • 3.3.1正面近
    • 3.3.2正面亮
    • 3.3.3正面暗
    • 3.3.4旋转
    • 3.3.5侧面
    • 3.3.6结论
  • 4.总结论
  • 5.遇到的问题
  • 二.Harris特征匹配
  • 代码

一.Harris角点检测

1.实验原理

1.1什么是角点

角点就是极值点,即在某方面属性特别突出的点,是在某些属性上强度最大或者最小的孤立点、线段的终点。而对于图像而言,如图所示红点部分,即为图像的角点,其是物体轮廓线的连接点。
因此,在角点时,窗口向任意方向的移动都导致图像灰度的明显变化。
Harris角点检测——python实现_第1张图片

1.2数学表达

假设图像像素点(x,y)的灰度为 I(x,y),以像素点为中心的窗口沿 x 和 y 方向分别移动 u 和 v 的灰度强度变化的表达式为:
在这里插入图片描述
其中 E(u,v)是灰度变化,w(x,y) 是窗口函数,一般是高斯函数,所以可以把w(x,y)看做是高斯滤波器。I(x,y)是图像灰度, I(x+u,y+v)是平移后的图像灰度。
收到泰勒公式的启发,在这里我们可以将 I(x+u,y+v)函数在(x,y)处泰勒展开,为了提高抗干扰的能力并且简化运算,我们取到了一阶导数部分,后面的无穷小量可以忽略,整理得到表达式如下:
Harris角点检测——python实现_第2张图片
将[ Ixu+Iyv ]展开后整理可以用矩阵表达为:
Harris角点检测——python实现_第3张图片

最后我们可以近似得到E(x,y)的表达式,将其化为二次型后得到:
Harris角点检测——python实现_第4张图片
其中M是一个2X2的矩阵,称为像素点的自相关矩阵,可以由图像的导数求得。M=窗口函数*偏导矩阵,表达式为:
Harris角点检测——python实现_第5张图片

因为u,v是局部微小的移动变量,所以我们对M进行讨论,M是一个2X2的矩阵,M的表达式中与点的位置(x,y)具体强相关性,记M得特征值为λ1,λ2,关于特征值的意义太过抽象,这里就不展开,但是我们可以简单理解为该点的灰度值变化速度,那么a1和a2可以分别看做是x方向和y方向的灰度变化速率,就可以用a1,a2两者的大小关系来进行分类。
当两个特征值λ1和λ2都偏小的时候,表示窗口沿任意方向移动都会使灰度变化很细微,该点处于图像的平坦区域。
当λ1>>λ2或者λ1<<λ2时,说明该点向水平(垂直)方向移动时变化会很明显,而向垂直(水平)方向则变化不明显,该点处于图像的边缘区。
当两个特征值λ1和λ2都很大的时候,表示窗口沿任意方向移动都会使灰度变化很明显,该点位置就是图像角点的位置。
Harris角点检测——python实现_第6张图片

然而在实际中,经常使用的是角点响应函数CRF这一概念,以此更加准确的计算所需角点,方法如下:

Harris角点检测——python实现_第7张图片
det M是矩阵M的行列式,Trace(M)为矩阵M的迹。k为修正值,是一个常数,经验取值为0.04-0.06。算出响应值之后,根据R与阈值T的比较来判断是否为角点。

当|R|很小时,R 当R<0时,R 当R>0时,R>T, 认为该点位置就是图像角点。

Harris角点检测——python实现_第8张图片

2.实验代码

compute_harris_response():在一幅灰度图像中,对每个像素计算harris角点检测器响应函数,返回像数值为Harris响应值的一幅图像
get_harris_points():从一幅harris响应图像中返回角点

# -*- coding: utf-8 -*-
from pylab import *
from PIL import Image
from PCV.localdescriptors import harris

"""
Example of detecting Harris corner points (Figure 2-1 in the book).
"""

# 读入图像
im = array(Image.open(r'C:\Python\Pictrue\group5_5.jpg').convert('L'))

# 检测harris角点

harrisim = harris.compute_harris_response(im)

# Harris响应函数
harrisim1 = 255 - harrisim

figure()
gray()

#画出Harris响应图
subplot(141)
imshow(harrisim1)
print harrisim1.shape
axis('off')
axis('equal')

threshold = [0.01, 0.05, 0.1]
for i, thres in enumerate(threshold):
    filtered_coords = harris.get_harris_points(harrisim, 6, thres)
    subplot(1, 4, i+2)
    imshow(im)
    print im.shape
    plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
    axis('off')

#原书采用的PCVPCV harris模块
#harris.plot_harris_points(im, filtered_coords)

# plot only 200 strongest
# harris.plot_harris_points(im, filtered_coords[:200])

show()

3.实验结果及分析

3.1边缘多的场景

3.1.1正面亮


Harris角点检测——python实现_第9张图片

3.1.2正面暗

Harris角点检测——python实现_第10张图片

3.1.3正面远


Harris角点检测——python实现_第11张图片

3.1.4旋转

Harris角点检测——python实现_第12张图片
Harris角点检测——python实现_第13张图片

3.1.5 侧面

Harris角点检测——python实现_第14张图片
Harris角点检测——python实现_第15张图片

3.1.6结论

在边缘多的场景中
(1)亮度:亮度较高的图片角点较多
(2)旋转:无太大变化
(3)正面侧面:无太大变化
(4)远近:无太大变化

3.2角点丰富的场景

3.2.1正面近


Harris角点检测——python实现_第16张图片

3.2.2正面亮


Harris角点检测——python实现_第17张图片

3.2.3正面暗


Harris角点检测——python实现_第18张图片

3.2.4旋转

Harris角点检测——python实现_第19张图片
Harris角点检测——python实现_第20张图片

3.2.5侧面


Harris角点检测——python实现_第21张图片

3.2.6结论

在角点丰富的场景中
(1)亮度:亮度较低的图片与亮度较高的图片相比角点更多
(2)旋转:图片的旋转对角点没有太大影响
(3)正面侧面:图片的正侧面对角点没有太大影响
(4)远近:远图角点较近图角点多

3.3纹理平坦的场景

3.3.1正面近

Harris角点检测——python实现_第22张图片
Harris角点检测——python实现_第23张图片

3.3.2正面亮

Harris角点检测——python实现_第24张图片
Harris角点检测——python实现_第25张图片

3.3.3正面暗

Harris角点检测——python实现_第26张图片
Harris角点检测——python实现_第27张图片

3.3.4旋转

Harris角点检测——python实现_第28张图片
Harris角点检测——python实现_第29张图片

3.3.5侧面

Harris角点检测——python实现_第30张图片
Harris角点检测——python实现_第31张图片

3.3.6结论

在平坦的场景中
(1)亮度:亮度较高的图片角点较多
(2)远近:无较大变化
(3)旋转:无较大变化
(4)正侧面:无较大变化

4.总结论

由上述得出以下结论:角点检测算子对亮度的变化更敏感敏感,角点更多,角点算子具有旋转不变性,正侧面对角点并没有太大影响,但是角点不具备尺度不变性。
平坦场景下角点变化很微小,边缘丰富场景下沿着边缘方向移动不会出现太大变化,角点多的情况下较其他两种情况会出现较大变化。

5.遇到的问题

有一个疑问没有解决:有一些图片放进去会出现不显示角点的情况,并且有runtime error,在网上找到的和我的情况都不是很符合,于是我就换了能用的图片继续实验。

二.Harris特征匹配

Harris角点检测器可以给出图像中检测到兴趣点,但它并没有提供在图像间对兴趣点进行比较的方法,我们需要在每个角点添加描述子,以及对这些描述子进行比较。

代码

1.get_descriptors():将图像块像素值压平成一个向量,然后添加到描述子列表中。

match():使用归一化的互相关矩阵,将每个描述子匹配到另一个图像中的最优的候选点。

match_twosided():从第二幅图像向第一幅图像进行匹配,然后过滤掉在两种方法中不都是最好的匹配。

 # -*- coding: utf-8 -*-
from pylab import *
from PIL import Image

from PCV.localdescriptors import harris
from PCV.tools.imtools import imresize

"""
This is the Harris point matching example in Figure 2-2.
"""

# Figure 2-2上面的图
#im1 = array(Image.open("../data/crans_1_small.jpg").convert("L"))
#im2= array(Image.open("../data/crans_2_small.jpg").convert("L"))

# Figure 2-2下面的图
im1 = array(Image.open(r'C:\Python\Pictrue\group5_1.jpg').convert("L"))
im2 = array(Image.open(r'C:\Python\Pictrue\group5_5.jpg').convert("L"))

# resize加快匹配速度
im1 = imresize(im1, (im1.shape[1]/2, im1.shape[0]/2))
im2 = imresize(im2, (im2.shape[1]/2, im2.shape[0]/2))

wid = 5
harrisim = harris.compute_harris_response(im1, 5)
filtered_coords1 = harris.get_harris_points(harrisim, wid+1)
d1 = harris.get_descriptors(im1, filtered_coords1, wid)

harrisim = harris.compute_harris_response(im2, 5)
filtered_coords2 = harris.get_harris_points(harrisim, wid+1)
d2 = harris.get_descriptors(im2, filtered_coords2, wid)

print 'starting matching'
matches = harris.match_twosided(d1, d2)

figure()
gray()
harris.plot_matches(im1, im2, filtered_coords1, filtered_coords2, matches)
show()

Harris角点检测——python实现_第32张图片

你可能感兴趣的:(Harris角点检测——python实现)