【CV】Harris角点检测

1 理论部分

1.1 角点

用一个滑动的窗口在图像内移动,分别会出现以下三种情况(如图1所示):

平坦区域(左图):当窗口向任意方向移动时,窗口内的像素值不会发生太大变化;
边缘(中图):当窗口沿着平行于边缘的方向移动时,窗口内的像素值不会发生太大变化;
角点(右图):不管窗口向着哪个方向移动,窗口内的像素值都会发生很大的改变。
在这里插入图片描述
图1. 角点的识别
1.2 图像梯度

图像的梯度,指的是图像灰度值的变化率。由于图像灰度变化并不连续,因此采用差分法来求梯度。如点(x,y)处在x方向和y方向的梯度可按下式计算:
Gx(x,y)=H(x+1,y)−H(x−1,y)
(x,y)=H(x+1,y)−H(x−1,y)
Gy(x,y)=H(x,y+1)−H(x,y−1)

(x,y)=H(x,y+1)−H(x,y−1)

1.3 Harris角点检测算法思想

(n−k),k<n。
所以,可以得出这样的结论:
增大k的值,将减小角点响应值R,降低角点检测的灵性,减少被检测角点的数量;
减小k值,将增大角点响应值R,增加角点检测的灵敏性,增加被检测角点的数量。

2.对亮度和对比度的变化不敏感
Harris算法采用图像梯度或微分来进行运算,而梯度或微分对图像密度的拉升哦收缩,以及对亮度的升高或降低不明感。也就是说,对亮度和对比度的仿射变换并不改变极值点出现的位置。但是阈值选择的不同会影响检测角点的数量。

在这里插入图片描述
图4. 部分不变性
3.旋转不变性
Harris角点检测算子使用的是角点附近的区域灰度二阶矩矩阵。而二阶矩矩阵可以表示成一个椭圆,椭圆的长短轴正是二阶矩矩阵特征值平方根的倒数。当特征椭圆转动时,特征值并不发生变化,所以判断角点响应值R也不发生变化,由此说明Harris角点检测算子具有旋转不变性。

在这里插入图片描述

图5. 用椭圆表示二阶矩矩阵

4.不具有尺度不变性
当图像被缩小时,所检测出的角点可能是完全不一样的。
在这里插入图片描述

图6. 不具有尺度不变性

2 实践部分

OpenCV中有可直接调用的Harris角点检测的函数:

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

参数解释:

src – 输入的灰度图像,float32类型;
blockSize - 用于角点检测的邻域大小,就是上面提到的窗口的尺寸;
ksize - 用于计算梯度的Sobel算子的尺寸;
k - 用于计算角点响应函数的参数k,取值在0.04~0.06之间;
dst - 存储着Harris角点响应的图像矩阵,大小与输入图像大小相同,是一个浮点型矩阵;
borderType - 边界处理的类型。
下面基于python进行Harris角点检测:

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('Building.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))

# Convert BGR to Gray
gray_img = cv.cvtColor(image, cv.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 = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
# 取核中像素值的最大值,代替核的中心位置(锚点)处的像素值
dst = cv.dilate(corners_img, kernel)

# Threshold for an optimal value, marking the corners in Red
for r in range(height):
    for c in range(width):
        pix = dst[r, c]
        if pix > 0.05 * dst.max():
            cv.circle(image, (c, r), 5, (0, 0, 255), 0)

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

在这里插入图片描述

在这里插入图片描述
图7. 角点检测结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值