计算机视觉——Harris角点检测

Harris角点检测原理

角点的概念

角点通常被定义为两条边的交点,更严格的说,角点的局部邻域应该具有两个不同区域的不同方向的边界。或者说,角点就是多条轮廓线之间的交点。
直观上或者从字面意思上很容易看出角点是什么,在哪里,那么从数字图像处理的角度来看的话,可以描述如下:

  1. 像素点附近区域像素无论是在梯度方向、还是在梯度幅值上都发生较大的变化。
  2. 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
  3. 两条及两条以上边缘的交点;
  4. 图像中梯度值和梯度方向的变化速率都很高的点;
  5. 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。

角点检测的意义

首先角点是图像中很重要的特征,对图像图形的理解和分析有很重要的作用。角点在保留图像图形重要特征的同时,可以有效地减少信息的数据量,使其信息的含量很高,有效地提高了计算的速度,有利于图像的可靠匹配,使得实时处理成为可能。对于同一场景,即使视角发生变化,角点通常具备稳定性质的特征。
角点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,由于角点检测的实时性以及稳定性,广泛应用于运动检测、图像匹配、视频跟踪、三维建模和目标识别等领域中。角点作为一种特征点,角点检测也称为特征点检测。
在实际的视觉用用中,大多数的角点检测方法检测的是拥有特定特征的图像点,而不仅仅是“角点”。这些特征点在图像中有具体的坐标,并具有某些数学特征,如局部最大或最小灰度、某些梯度特征等。

Harris 角点检测

角点检测算法基本思想是使用一个固定窗口(取某个像素的一个邻域窗口)在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。
首先我们用数学的方法描述一下窗口在图片上滑动时像素点灰度变化描述:
公式

  1. [u,v]是窗口的偏移量
  2. (x,y)是窗口内所对应的像素坐标位置,窗口有多大,就有多少个位置
  3. w(x,y)是窗口函数
  4. I(x,y) 是平移前窗口某点的像素值,I(x+u,y_v)时窗口平移后对应点的像素值
    我们通过对灰度变化部分(即有uv参加的部分)进行泰勒展开得到:
    公式
    其中第一个约等于是对I(x+u,y+v)的一阶近似,其中Ix和Iy分别是像素在x,y方向上的梯度。下一个等号是对一阶近似后的式子化简再做平方展开得到的,改写成矩阵的形式侧可以得到最后的结果
    所以我们可以将E(u,v)进行整理得
    公式
    其中M是 2*2 矩阵,可由图像的导数求得:
    公式
    Harris检测数学表达:
    通过M的两个特征值的大小对图像点进行分类:
    数学表达
    公式
    • R 只与M的特征值有关
    • 角点:R 为大数值正数
    • 边缘:R为大数值负数
    • 平坦区:R为小数值

代码

# -*- 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('data/p1_front.jpg').convert('L'))

# 检测harris角点
harrisim = harris.compute_harris_response(im)

# Harris响应函数
harrisim1 = 255 - harrisim

figure()
gray()

#画出Harris响应图
subplot(221)
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(2, 2, i+2)
    imshow(im)
    print (im.shape)
    plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
    axis('off')

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

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

show()

结果预测

将输出图片的尺寸,画出Harris检测相应图,以及展示不同阈值处理下Harris角点预测的结果图。阈值分别为0.01, 0.05, 0.1

纹理角点丰富处的Harris检测

正向场景

结果

侧向场景

结果

旋转图片

结果

改变尺度

结果

改变光照

结果

结论

本次选用格子背景的图片,可以说其中的角点比较丰富。

  1. 正侧对比:正向拍摄的图片相较于侧面拍摄的图片检测出的角点更多
  2. 旋转对比:通过结果可以看出正向拍摄的图片与旋转拍摄的图检测出的角点差不多多,可以推测Harris角点检测对角点丰富具有一定的旋转不变性
  3. 尺度(远近)对比:在本次实验中,在更远的地方拍的图片检测出的角点更多
  4. 光照对比:当阈值较小时,检测出的角点个数差不多,但是阈值越大,光照多的图片检测出的角点个数就更少

垂直边缘多处的Harris检测

正向场景

结果

侧向场景

结果

旋转图片

结果

改变尺度

结果

改变光照

结果

结论

本次选用建筑相关的图片,可以说其中的边缘比较丰富。

  1. 正侧对比:可能由于正向的窗户可以被拍出来更多,因此本次实验中正向拍摄的图片检测出来的角点更多
  2. 旋转对比:通过结果可以看出正向拍摄的图片相比较旋转后的图片检测出的角点更多更密集
  3. 尺度(远近)对比:在本次实验中,更近拍摄的图片检测出的角点更少,也比较稀疏
  4. 光照对比:在本次选取的建筑光照改变对比中,光照对角点检测影响不大

纹理平坦处的Harris检测

正向场景

结果

侧向场景

结果

旋转图片

结果

改变尺度

结果

改变光照

结果

结论

本次选用一个盒子在桌子上的图片,盒子和桌子都没有什么纹理。

  1. 正侧对比:在本次实验结果中,可以看出正向拍摄的和侧面拍摄的图像角点个数差不多
  2. 旋转对比:通过结果可以看出正向拍摄的图片与旋转拍摄的图检测出的角点差不多多,可以推测Harris角点检测对角点丰富具有一定的旋转不变性
  3. 尺度(远近)对比:在更近拍摄的图像中,阈值较小时检测出的盒子的边缘角点比较多,在比较元拍摄的图像中,阈值较小的时候检测出无效角点比较多
  4. 光照对比:在本次选取的光照改变对比中,光照对角点检测影响不大

总结

在本次实验中,可以看到,无论是在纹理角点丰富的场景下,还是在垂直边缘多的场景下,还是在纹理平坦处,阈值较小的时候检测出的角点更多,其中有相当一部分是无效的角点,阈值越大,检测出的角点越少。但并不是阈值越大越好,比如在纹理角点丰富的场景下,光照更强的时候,阈值越大,检测出来的角点太少,可以说丢失了很多角点。
一般来说,其他条件相同时,无论怎么旋转,检测出的角点差不多,但是改变光照,对于角点检测影响较大。通过实验还可以发现,在纹理角点丰富的场景下,应该选择较小的阈值,但是在边缘较多和纹理平坦处,影响选择较大的阈值防止检测出很多无效角点。

问题

在实验过程中,我发现有一些照片不能进行角点检测,个人猜测可能是因为区域内没有角点,所以检测不出;或者是图像清晰度太低;希望大佬解答。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值