OpenCV中的几种角点检测方法

本文深入介绍了OpenCV中的角点检测算法,包括Harris角点检测、Shi-Tomas改进算法、尺度不变特征转换(SIFT)、快速角点检测(FAST)和Oriented FAST and Rotated BRIEF(ORB)。每个算法的原理、实现步骤和优缺点进行了详细阐述,并提供了相应的代码示例,展示了如何在图像中检测和标记角点。

1.Harris角点检测

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

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正确显示中文

# Harris角点检测
'''
Harris角点检测的思想是通过图像的局部小窗口观察图像,角点的特征是窗口沿任意方向移动都会导致
图像灰度的明显变化

将上述思想转化为数学表达式,即将局部窗口向各个方向移动(u,v)并计算所有灰度差异的总和,表达式
如下:
    E(u,v)=∑w(x,y)[I(x+u,y+v)-I(x,y)]²
其中I(x,y)是局部窗口的灰度图,I(x+u,y+v)是平移后的灰度图像,w(x,y)是窗口函数,其可以是矩形
窗口,也可以是对每一个像素赋予不同权重的高斯窗口
角点检测中使E(u,v)的值最大.利用一阶泰勒展开有:
    I(x+u,y+v)=I(x,y)+Ix*u+Iy*v
    其中:Ix和Iy是沿x和y方向的导数,可用sobel算子计算.
    
    E(u,v)=∑w(x,y)[I(x+u,y+v)-I(x,y)]²
          =∑w(x,y)[Ix²u²+2Ix*Iy*u*v+Iy²*v²]
                       |Ix² Ix*Iy|
          =∑w(x,y)[u,v]|Ix*Iy Iy²|
          
          =[u v]M|u|
                 |v|
                 
    M矩阵决定了E(u,v)的取值,M是Ix和Iy的二次函数,可以表示成椭圆的形状,椭圆的长短半轴由M的特征
    值a1和a2决定,方向由特征矢量决定
    
 
 共可分为三种情况:
    .图像中的直线.一个特征值大,另一个特征值小,a1>>a2或者a2>>a1.椭圆函数值在某一个方向上大,
    在其他方向小
    .图像中的平面.两个特征值都小,且近似相等,椭圆函数值再各个方向都有
    .图像中的角点.两个特征值都大,且近似相等,椭圆函数在所有方向都增大.

 Harris给出的角点计算方法并不需要计算具体的特征值,而是计算一个角点响应值R来判断角点.R的计算公式
 为:
    R=detM-α(traceM)²
    式中,detM为矩阵M的行列式,traceM为矩阵M的迹,α为常数取值范围为0.04~0.06.事实上,特征是隐含
    在detM和traceM中,因为:
        detM=a1a2
        traceM=a1+a2

    那么认为:
    .当R为大数时的正数是角点
    .当R为大数时的负数为边界
    .当R为小数认为是平坦区域
    

API:
    cv.cornerHarris(src,blockSize,ksize,k)
    参数:
        img:数据类型为float32的输入图像
        blockSize:角点检测中要考虑的领域大小
        ksize:sobel算子求导使用的核大小
        k:角点检测中的自由参数取值范围为[0.04,0.06]
   
'''

# 读取图片
img = cv.imread('image/house.jpg')

# 转换成灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 数据类型转换成float32
gray_float32 = np.float32(gray)

# 角点检测
dst = cv.cornerHarris(gray_float32, 2, 3, 0.04)

#设置阈值,将角点绘制出来,阈值根据图像进行选择
R=dst.max() * 0.01
#这里将阈值设为dst.max()*0.01 只有大于这个值的数才认为数角点
img[dst > R] = [0, 0, 255]


plt.subplot(2,2,1)
plt.imshow(cv.imread('image/house.jpg')[:,:,::-1])
plt.title('原图')

plt.subplot(2,2,2)
plt.imshow(gray,cmap=plt.cm.gray)
plt.title('灰度图(uint8型)')

plt.subplot(2,2,3)
plt.imshow(gray_float32,cmap=plt.cm.gray)
plt.title
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值