Harris特征点检测器

刚好看到datewhale关于opencv的学习部分,想着借机会熟悉一下opencv部分的内容,第一部分是harris特征点检测器部分的内容,之前学视觉SLAM的视觉就接触过一些特征点检测和计算描述子的方法,又跟着系统学习了一下关于harris特征点的计算方法,收获蛮大~

基础知识

角点:字面意思就是一些边角上的点,在之前的ORB的提取中就是看当前的点与周围一圈12个点,有多少个点是不同的,通常采用九点法,在harris中就采用了图像梯度的概念,即看当前点与周围点的变化幅度有多大,考虑图像的每个像素的某个邻域内的灰度变化

算法思想:核心即在局部窗口中在图像上进行移动,判断灰度是否发生了较大的变化,如果发生了较大变化,那么这个窗口所在区域就存在角点

算法分为以下三个步骤

  • 窗口同时向x和y方向移动,计算窗口内部的像素值变化量
  • 对于每个窗口,计算对应的一个角点响应函数
  • 对函数进行一个阈值判断,如果大于阈值,则认为该窗口存在角点特征

数学模型

第一步 建立数学模型

第一步给当前的像素一个小的移动量,类似于给一个小扰动,得到新的位置的像素灰度值,对于窗口内的像素要给以响应的权重,最简单就是给所有像素权重为1,复杂一些可以认为符合高斯分布,认为窗口中心像素点贡献较大,离窗口中心较远的点,这些点的灰度变化影响比较小,可以把他们的权重设置的低一些,可以通过泰勒公式进行简化优化。

第二步 响应矩阵R

前面一步已经得到了 E ( u , v ) E(u,v) E(u,v)的最终形式,灰度值变化的大小取决于矩阵M,为了编程方便,定义了角点响应函数R,通过判断R大小,来判断像素是否为角点

第三步 角点判断

根据R的值,将这个窗口所在的区域划分为平面,边缘或角点,为了得到最优的角点,还可以使用非极大值抑制

harris检测器具有旋转不变性,但是不具有尺度不变性,即尺度变化可能会使得角点变成边缘,如果想要尺度不变,可以关注sift特征

具体实现部分

opencv提供了实现harris角点检测的函数cv2.cornerHarris,对于每一个像素(x,y), 计算梯度图的协方差矩阵 M ( x , y ) M(x,y) M(x,y),然后通过上面第二步中的角点响应函数得到结果图。图像中的角点可以为该结果图的局部最大值。
函数原型:

cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])

代码示例如下:

import cv2 as cv
from matplotlib import pyplot as plt
import numpy as np

# detector parameters
block_size = 3
sobel_size = 3
k = 0.06

image = cv.imread('Scenery.jpg')

print(image.shape)
height = image.shape[0]
width = image.shape[1]
channels = image.shape[2]
print("width: %s  height: %s  channels: %s"%(width, height, channels))
   
gray_img = cv.cvtColor(image, cv2.COLOR_BGR2GRAY)


# modify the data type setting to 32-bit floating point 
gray_img = np.float32(gray_img)

# detect the corners with appropriate values as input parameters
corners_img = cv.cornerHarris(gray_img, block_size, sobel_size, k)

# result is dilated for marking the corners, not necessary
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
dst = cv.dilate(corners_img, kernel)

# Threshold for an optimal value, marking the corners in Green
#image[corners_img>0.01*corners_img.max()] = [0,0,255]

for r in range(height):
        for c in range(width):
            pix=dst[r,c]
            if pix>0.05*dst.max():
               cv2.circle(image,(c,r),5,(0,0,255),0)

image = cv.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(image)
plt.show()

代码就直接搬运了datewhale的啦,还是比较通俗易懂的~

总结
  • 阈值决定了角点的数量,阈值越高,则能被筛选出来的角点越少
  • harris角点检测算子具有光照不变性
  • harris具有旋转不变性
  • harris角点检测算子不具有尺度不变性,所以需要考虑加上sift等方法
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值