图像的特征点检测-Opencv实现

1.基本概念

特征点:
可以理解为区别于其它部分或物体的地方。根据特征应该能准确、唯一地识别出对应目标。 例如在一堆青苹果中,有几个红苹果。那么红色就是可以准确识别出红苹果的有效特征。人眼对特征的识别通常是在一个局部的小区域或小窗口完成的。 如果在各个方向上移动这个特征的小窗口,窗口内区域的灰度发生了较大的变化,那么就认为在窗口内遇到了特征点。
特征检测:
在一幅图像上滑动比较,如果无论往哪个方向移动,窗口内容变化都很大,那么这个地方一定是角点。 如果沿某一方向无明显变化,沿另一方向变化很大,说明很有可能是边缘。如果无论哪个方向都没有变化,则可能是内部或外部的面状目标。
特征描述:
在一幅图中找到特征后,我们自然希望在其它图中也找到同样的特征。因此我们需要对特征进行描述。

2. 角点

2种角点的定义:
1.角点可以是两个边缘的交点
2.角点是邻域内具有两个主方向的特征点(主方向是法曲率取极值的方向,可参考微分几何)
在图像中,角点是重要特征,角点在保留图像重要特征的同时, 可以有效减少信息数据量,使其信息含量很高,有效提高了计算速度。这也就是为什么在做两幅影像的匹配配准之前, 需要先对图像提取特征点(角点)的原因。这样也使实时处理成为可能。 因此说角点在三维场景重建、运动估计、目标跟踪、目标识别、图像配准与匹配等领域有着非常重要的作用。

检测角点的算法

1.Moravec角点检测算子
在图像上取一个w×w的滑动窗口(如3×3),不断移动这个窗口, 依次计算在8个方向上的灰度变化V(上、下、左、右以及四个对角)。 V会有三种情况:
如果窗口中的图像是平坦的,那么灰度变化不大
如果窗口中的图像是边缘,那么在沿边缘时变化不大,在垂直于边缘时变化较大
如果窗口中的图像是角点,那么沿任何方向,灰度变化都很大
而V可以用以下公式表示:
V ( x , y ) = ∑ x , y ( I x + u , y + v − I x , y ) 2 V(x,y)=\sum_{x,y}(I_{x+u,y+v}-I_{x,y})^2 V(x,y)=x,y(Ix+u,y+vIx,y)2

2.Harris角点检测算子
在这里插入图片描述在这里插入图片描述在这里插入图片描述
注意:
1.R值较大且为正数时,为角点。R值较大且为负数时,为边缘。R值较小时,为平坦区域。 在判断角点时,对角点响应函数R进行阈值处理,提取局部极大值,当R大于阈值时,认为是角点。
2. I x , I y I_x,I_y Ix,Iy用sobel算子计算。
3.Shi-Tomasi角点检测算子
与Harris算子不同之处在于打分函数R。
在Harris算子中,打分函数如下:
R = d e t ( M ) − k ( t r a c e ( M ) ) 2 R=det(M)−k(trace(M))^2 R=det(M)k(trace(M))2
但在Shi-Tomasi算子中对其进行了改进,变成了如下形式:
R = m i n ( λ 1 , λ 2 ) R=min(λ_1,λ_2) R=min(λ1,λ2)
对得分进行阈值判断,超过阈值即认为是角点。只有当λ1和λ2都大于最小值时,才被认为是角点。

3. 实现

实现Harris角点检测算子

函数:cv2.cornerHarris(输入图像,角点检测邻域的大小,Sobel求导时使用的窗口大小,角点检测参数k)
返回:R

import cv2
import numpy as np
from matplotlib import pyplot as plt
plt.rcParams["font.family"] = "SimHei"#直接修改配置字典,设置默认字体
img = cv2.imread("E:/ruanjianDM/jupyternoerbookDM/Opencv3/data/boniu.png")

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 由于Harris算子需要float32的输入图像,因此转换一下数据格式
gray = np.float32(gray)

# 调用Harris算子
R = cv2.cornerHarris(gray, 2, 3, 0.04)

# 0.01是人为设定的阈值,值越小,角点越多
img[R > 0.01 * R.max()] = [0, 255, 255]

plt.subplot(121),plt.imshow(R, cmap='gray')
plt.title("R灰度图像")
plt.subplot(122),plt.imshow(img[:,:,::-1])
plt.title("角点检测图像")

在这里插入图片描述

实现Shi-Tomasi角点检测算子

函数:cv2.goodFeaturesToTrack(图像,检测角点的数目N,角点质量,角点间的最短距离)
返回:获取图像中N个最好的角点。
根据这些信息,函数就能在图像上找到角点。所有低于质量水平的角点都会被忽略。 然后再把合格角点按角点质量进行降序排列。 函数会采用角点质量最高的那个角点(排序后的第一个), 然后将它附近(最小距离之内)的角点都删掉。按这样的方式最后返回N个最佳角点。

# coding=utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt
plt.rcParams["font.family"] = "SimHei"#直接修改配置字典,设置默认字体
img = cv2.imread("E:/ruanjianDM/jupyternoerbookDM/Opencv3/data/boniu.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 调用Shi-Tomasi角点检测算子
corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 10)

# 将浮点型数据转成int型,否则无法绘制
corners = np.int0(corners)

for i in corners:
    # 将每一项拆开,在重新拼成一个元组
    x, y = i.ravel() #将1x1x2变成1x2
    # 在图上绘制角点,为了更好显示,设置半径为2
    cv2.circle(img, (x, y), 2, (0, 255, 255), -1)
plt.imshow(img[:,:,::-1])

在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值