一.角点特征
图像的特征
图像的特征是指能够描述图像本质属性、区分不同图像的视觉信息或抽象属性,是计算机视觉、图像处理等领域分析和理解图像的基础。这些特征可以从多个维度进行分类和解读,具体如下:
基于视觉感知的底层特征
这类特征是人类视觉系统能直接观察到的基本属性,也是计算机处理图像时首先提取的信息。
-
颜色特征
- 描述图像中像素的颜色组成和分布,是最直观的特征之一。
- 常见表示方式:
- 颜色空间(如 RGB、HSV、Lab 等):不同空间对颜色的描述侧重不同,例如 HSV 更符合人类对色彩(Hue)、饱和度(Saturation)、明度(Value)的感知。
- 颜色直方图:统计图像中每种颜色出现的频率,可用于快速比较图像的色调分布(如红色主导的图像 vs 蓝色主导的图像)。
- 应用:图像检索(如按 “红色花朵” 搜索)、肤色检测、产品颜色分类等。
-
纹理特征
- 描述图像中像素的排列规律,体现物体表面的粗糙、平滑、条纹、斑点等质感。
- 常见类型:
- 规则纹理:如布料的格子、砖墙的缝隙,具有周期性重复模式。
- 不规则纹理:如树皮、云朵,无明显重复规律但有整体质感。
- 提取方法:通过灰度共生矩阵(统计像素间灰度关系)、LBP 算子(局部二值模式)等量化。
- 应用:区分布料(丝绸 vs 牛仔)、识别卫星图像中的土地类型(森林 vs 沙漠)。
-
形状特征
- 描述图像中物体的轮廓或几何形态,如圆形、方形、不规则曲线等。
- 关键属性:
- 轮廓:物体边缘的连续线条(如苹果的弧形轮廓)。
- 面积、周长、长宽比:量化形状的大小和比例(如邮票的 “狭长形”)。
- 矩特征:通过数学计算描述形状的对称性、中心位置等(如正三角形的中心对称特征)。
- 应用:工业质检(检测零件是否为标准圆形)、手写数字识别(区分 “0” 和 “6” 的形状差异)。
-
空间分布特征
- 描述图像中像素或物体的位置关系,如 “上下”“左右”“包围” 等。
- 示例:一幅 “太阳在山顶上方” 的图像中,太阳与山的 “上下分布” 就是关键空间特征。
- 应用:场景理解(如 “教室” 场景中 “黑板在讲台上方” 的布局)、图像语义分割(标注物体间的位置关联)。
基于语义理解的高层特征
这类特征需要结合知识或上下文,反映图像的抽象含义,超越了底层视觉信息。
-
语义内容
- 图像所表达的实际意义,如 “一只猫在沙发上睡觉”“城市夜景” 等。
- 依赖底层特征的组合:例如 “猫” 的语义需要颜色(毛色)、形状(流线型身体、尖耳朵)、纹理(毛发质感)等底层特征共同支撑。
-
情感与风格特征
- 图像传递的情感倾向(如温暖、压抑、欢快)或艺术风格(如油画、素描、卡通)。
- 示例:梵高的《星月夜》通过扭曲的线条和强烈的色彩对比,体现 “狂放” 的风格特征;黑白老照片常带有 “怀旧” 的情感特征。
特征的提取与应用
- 提取方式:
- 传统方法:手动设计算子(如 SIFT 特征用于匹配图像中的关键点)。
- 深度学习:通过卷积神经网络(CNN)自动学习特征(如从图像中逐层提取边缘→纹理→形状→语义)。
- 核心作用:
特征是图像分析的 “语言”—— 通过提取和比对特征,计算机可以实现图像分类、目标检测、图像检索、人脸识别等任务(例如人脸识别中,眼睛间距、鼻梁轮廓等特征是区分不同人的关键)。
二.Harris和Shi-Tomas算法
1.Harris角点检测
1.原理
Harris 角点检测是计算机视觉中经典的角点检测算法,由 Chris Harris 和 Mike Stephens 于 1988 年提出。其核心是通过分析图像局部窗口的灰度变化,判断该区域是否为角点(图像中局部曲率突变的点,如拐角、边缘交点等)。
Harris 算法的核心思想是:通过计算局部窗口在不同方向移动时的灰度变化量,判断窗口中心是否为角点。
2.实现
dst = cv2.cornerHarris(src,blockNess,ksize,k)
img:数据类型为float32的输入图像
blockNess:角点检测要考虑的领域大小
ksize:求导使用的核的大小
k:角点检测方程中的自由参数
实例
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
#1 读取图像,并转换成灰度图像
img =cv.imread('./image/1.jpg')
gray =cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#2角点检测
#2,1 输入图像必须是float32
gray = np.float32(gray)
# 2.2 最后一个参数在 0.04到0.05之间
dst = cv.cornerHarris(gray,2,3,0.04)
#3 设置阈值,将角点绘制出来。阈值根据图像进行选择
img[dst>0.001*dst.max()] = [0,0,255]
#4图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('Harris')
plt.xticks([]),plt.yticks([])
plt.show()
2.Shi-Tomas角点检测
1.原理
Shi-Tomasi 角点检测是 Harris 角点检测的改进算法,由 Jianbo Shi 和 Carlo Tomasi 在 1994 年的论文《Good Features to Track》中提出。其核心思想是通过优化角点响应函数,选择 “更稳定、更适合跟踪” 的角点,在计算机视觉中广泛应用于特征点提取和目标跟踪。
Shi-Tomasi 角点检测步骤
与 Harris 算法类似,但在响应函数计算和角点筛选上有差异:
- 预处理:转换为灰度图,高斯平滑降噪;
- 计算梯度:用 Sobel 算子计算Ix,Iy;
- 计算梯度协方差矩阵M:
(通常用高斯窗口加权求和,增强抗噪性); - 计算特征值:对每个窗口的M计算特征值λ1,λ2;
- 响应函数计算:R=min(λ1,λ2);
- 阈值筛选:保留R≥threshold的点作为候选角点;
- 非极大值抑制:在局部邻域内保留响应值最大的点,避免冗余;
- 可选:角点排序与数量控制:按响应值降序排列,选择前N个角点(如 OpenCV 中的
goodFeaturesToTrack
函数)。
2.实现
corners = cv2.goodFeaturesToTrack(image,maxcorners,qualitylevel,minDistance)
image:输入灰度图像
maxcorners:获取角点数的数目
qualitylevel:该参数指出最低可接受的角点质量水平
minDistance:角点之间最小的欧式距离,避免得到相邻特征点
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1读取图像
img = cv.imread('./image/1.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 2 角点检测
corners = cv.goodFeaturesToTrack(gray, 1000, 0.01, 10)
# 3 绘制角点(修正部分)
for i in corners:
x, y = i.ravel()
cv.circle(img, (int(x), int(y)), 3, (0, 255, 0), -1) #使用固定半径3
# 4 图像展示
plt.figure(figsize=(10, 8), dpi=100)
plt.imshow(img[:, :, ::-1]), plt.title('shi-tomasi')
plt.xticks([]), plt.yticks([])
plt.show()
三.SIFT/SURF算法
1.SIFT原理
SIFT(Scale-Invariant Feature Transform,尺度不变特征变换)是由 David Lowe 于 1999 年提出的一种局部特征提取算法,其核心是在图像中提取具有尺度不变性和旋转不变性的特征点,广泛应用于图像匹配、目标识别、全景拼接等领域。
SIFT 算法的核心流程可分为四步:尺度空间极值检测、关键点定位、方向赋值、关键点描述符生成。
尺度空间极值检测
目标:在不同尺度下检测稳定的特征点(避免因物体远近导致的尺度变化影响特征匹配)。
1. 尺度空间的构建
尺度空间是通过对图像进行多尺度高斯模糊生成的,目的是模拟人眼在不同距离观察物体的效果(近看细节清晰,远看轮廓模糊)。
-
高斯金字塔:
将图像分为若干组(Octave),每组包含若干层(Scale)。- 组(Octave):每组图像的尺寸是上一组的 1/2(下采样),模拟 “更远距离” 的观察。
- 层(Scale):同一组内,使用不同标准差 σ 的高斯核对图像进行模糊,σ 逐渐增大(模糊程度增加)。
高斯模糊公式:
G(x,y,σ)=2πσ21e−(x2+y2)/(2σ2)
其中,σ 是尺度参数(σ 越大,模糊程度越高)。
-
差分高斯金字塔(DoG):
为了高效检测尺度空间中的极值点,计算相邻两层高斯模糊图像的差值,得到 DoG 图像:
D(x,y,σ)=(G(x,y,kσ)−G(x,y,σ))∗I(x,y)
其中,k 是尺度因子(同一组内相邻层的 σ 比值,通常取k=21/s,s 为每组的层数)。
DoG 可以近似高斯 - 拉普拉斯算子(LoG),而 LoG 是检测图像局部极值的有效工具,但 DoG 计算更高效。
2. 局部极值点检测
在 DoG 金字塔中,每个像素点需要与自身所在层的 8 个邻域像素以及相邻上下两层的 18 个像素(共 26 个点)进行比较,若该点是局部最大值或最小值,则被视为潜在的尺度不变特征点。
关键点定位
目标:剔除低对比度点和边缘点,保留稳定的关键点。
1. 精确位置与尺度计算
通过对 DoG 函数进行泰勒展开,拟合局部极值点的精确位置和尺度:
设 DoG 函数为D(x,y,σ),在极值点(x0,y0,σ0)附近展开为泰勒级数:
D(X)=D+∇DTX+21XTHX
其中X=(x,y,σ)T,∇D是梯度,H是 Hessian 矩阵。通过求解∇D(X)=0,得到精确极值点坐标,若其函数值(对比度)小于阈值(通常取 0.03),则剔除(低对比度点不稳定)。
2. 边缘点剔除
边缘点在一个方向上梯度变化大,另一个方向变化小,稳定性差。利用 Hessian 矩阵的主曲率判断是否为边缘点:
Hessian 矩阵H的主曲率α和β满足:
- 迹Tr(H)=Dxx+Dyy
- 行列式Det(H)=DxxDyy−Dxy2
主曲率的比值r=α/β,若(r+1)2/r<(t+1)2/t(t为阈值,通常取 10),则保留;否则剔除(边缘点)。
方向赋值
目标:为关键点分配主方向,使特征点具有旋转不变性。
1. 梯度计算
对关键点邻域(以关键点为中心,3×1.5σ 的区域)内的像素计算梯度方向和幅值:
- 梯度幅值:m(x,y)=(Lx)2+(Ly)2(Lx、Ly是 x、y 方向的梯度)
- 梯度方向:θ(x,y)=arctan2(Ly,Lx)(范围 0°~360°)
2. 方向直方图生成
统计邻域内梯度方向的分布,生成16 bin 的方向直方图(每个 bin 对应 22.5°),直方图的峰值对应的方向即为关键点的主方向。
若存在其他峰值超过主峰值的 80%,则将其作为辅助方向(增加匹配鲁棒性)。
关键点描述符生成
目标:生成对光照、旋转、尺度变化鲁棒的特征向量,用于后续匹配。
1. 区域旋转与梯度计算
将关键点邻域旋转至主方向(确保旋转不变性),取 16×16 的区域,并划分为 4×4 的子块(共 16 个子块)。
对每个子块计算 8 bin 的梯度方向直方图(每个 bin 对应 45°),统计子块内梯度的幅值和方向。
2. 生成 128 维特征向量
每个 4×4 子块的 8 bin 直方图对应 8 个值,16 个子块共 16×8=128 个值,形成 128 维特征向量。
为增强光照鲁棒性,对特征向量进行归一化处理(模长为 1),可进一步剔除光照线性变化的影响。
2.SURF算法
特性 | SIFT | SURF |
---|---|---|
提出时间 | 1999 年(David Lowe) | 2006 年(Herbert Bay 等) |
尺度空间 | 高斯差分(DoG)金字塔 | 盒式滤波器(Box Filter)+ 积分图像 |
关键点检测 | 局部极值点(DoG) | 黑塞矩阵(Hessian Matrix)行列式 |
方向赋值 | 梯度方向直方图(16 bins) | Haar 小波响应的主方向(x、y 方向) |
描述符生成 | 16×16 区域划分为 4×4 子块,8 bins / 子块 | 20×20 区域划分为 4×4 子块,4 维 Haar 响应 / 子块 |
描述符维度 | 128 维 | 64 维(默认)或 128 维 |
旋转不变性 | 强(基于梯度方向直方图) | 中(基于 Haar 小波主方向) |
尺度不变性 | 强(多尺度高斯金字塔) | 中(离散尺度采样) |
计算速度 | 慢(浮点运算多,涉及高斯卷积) | 快(积分图像加速盒式滤波) |
内存需求 | 高(需存储多尺度图像) | 低(仅需存储积分图像) |
抗噪性 | 中(高斯模糊平滑噪声) | 强(盒式滤波天然抗噪) |
专利情况 | 受专利保护(2004-2020,现已过期) | 开源(BSD 许可证) |
适用场景 | 高精度匹配(如医学图像、文物鉴定) | 实时应用(如 SLAM、无人机导航) |
3.实现
(1)实例化sift
sift = cv2.xfeatures2d.SIFT_create()
(2)利用sift.detectAndCompute()检测关键点并计算
kp,des = sift.detectAndCompute(gray,None)
gray:进行关键点检测的图像,灰度图
kp:关键点信息,包括位置,尺度,方向信息
des:关键点描述符
(3)将关键点检测结果绘制在图像上
cv2.drawKeypoints(image,keypoints,outputimage,color,flags)
image:原始图像
keypoints:关键点信息,将其绘制在图像上
outputimage:输出图片可以是原始图片
color:颜色设置,修改b,g,r更改画笔的颜色
flags:绘图功能的标识设置
cv2.DrawMatchesFlags.DEFAULT
默认绘制方式,仅绘制关键点的位置(以小圆圈表示),不显示方向和大小信息。
cv2.DrawMatchesFlags.DRAW_RICH_KEYPOINTS
绘制关键点的大小(圆的半径表示关键点的尺度)和方向(从圆心出发的线段表示方向)。
cv2.DrawMatchesFlags.DRAW_OVER_OUTIMG
作用在输出图像上叠加绘制关键点,不清除输出图像原有的内容。
cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS
作用:仅在匹配关键点时绘制(即当关键点作为匹配对的一部分时才绘制),单独的关键点不绘制。该标志主要用于cv2.drawMatches()
函数,在cv2.drawKeypoints()
中使用时可能无实际效果。
(4)实例
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
#1 读取图像
img = cv.imread('./image/1.jpg')
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 2 sift关键点检测# 2.1 实例化sift对象
sift = cv.xfeatures2d.SIFT_create()
# 2.2 关键点检测:kp关键点信息包括方向,尺度,位置信息,des是关键点的描述符
kp,des=sift.detectAndCompute(gray,None)# 2.3在图像上绘制关键点的检测结果
cv.drawKeypoints(img,kp,img,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)#3图像显示
plt.figure(figsize=(8,6),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('sift')
plt.xticks([]),plt.yticks([])
plt.show()
四.Fast和ORB算法
1.FAST算法
FAST(Features from Accelerated Segment Test)是一种快速角点检测算法,由 Edward Rosten 和 Tom Drummond 在 2006 年提出,专门用于需要实时处理的计算机视觉任务(如 SLAM、无人机导航)。其核心思想是通过高效的角点检测策略和机器学习方法,在保证检测精度的同时显著提升速度
(1)FAST 与其他角点检测算法的对比
算法 | 速度 | 尺度不变性 | 旋转不变性 | 抗噪性 | 应用场景 |
---|---|---|---|---|---|
FAST | 极快 | 否 | 否 | 较差 | 实时跟踪、无人机 |
Harris | 中 | 否 | 否 | 较好 | 传统计算机视觉 |
SIFT | 慢 | 是 | 是 | 较好 | 高精度匹配 |
SURF | 中快 | 是 | 是 | 较好 | 实时 + 高精度 |
(2)举例实现
1.实例化fast
fast = cv2.FastFeatureDetector_cerate(threshold,nonmaxSuppression)
threshold:阈值t,默认值10
nonmaxSuppression:是否进行非极大值抑制
2.利用fast.detect检测关键点
kp = fast.detect(grayImg,None)
grayImg:进行关键点检测的图片,灰度图
kp:关键点信息,包括位置,尺度,方向信息
3.将关键点检测结果绘制在图像上,与sift一样
cv2.drawKeypoints(image,keypoints,outputimage,color,flags)
image:原始图像
keypoints:关键点信息,将其绘制在图像上
outputimage:输出图片可以是原始图片
color:颜色设置,修改b,g,r更改画笔的颜色
flags:绘图功能的标识设置
cv2.DrawMatchesFlags.DEFAULT
默认绘制方式,仅绘制关键点的位置(以小圆圈表示),不显示方向和大小信息。
cv2.DrawMatchesFlags.DRAW_RICH_KEYPOINTS
绘制关键点的大小(圆的半径表示关键点的尺度)和方向(从圆心出发的线段表示方向)。
cv2.DrawMatchesFlags.DRAW_OVER_OUTIMG
作用在输出图像上叠加绘制关键点,不清除输出图像原有的内容。
cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS
作用:仅在匹配关键点时绘制(即当关键点作为匹配对的一部分时才绘制),单独的关键点不绘制。该标志主要用于cv2.drawMatches()
函数,在cv2.drawKeypoints()
中使用时可能无实际效果。
(3)实现
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
#1读取图像
img = cv.imread('./image/1.jpg')
# 2 Fast角点检测
# 2.1 创建一个Fast对象,传入阈值,注意:可以处理彩色空间图像
fast =cv.FastFeatureDetector_create(threshold=30)
# 2.2检测图像上的关键点
kp = fast.detect(img,None)
# 2.3 在图像上绘制关键点
img2 =cv.drawKeypoints(img,kp,None,color=(0,0,255))
# 2.4输出默认参数
print("Threshold: {}".format(fast.getThreshold()))
print("nonmaxSuppression:{}".format(fast.getNonmaxSuppression()))
print("neighborhood: {}".format(fast.getType()))
print("Total Keypoints with nonmaxSuppression: {}".format(len(kp)))
# 2.5 关闭非极大值抑制
fast.setNonmaxSuppression(0)
kp = fast.detect(img,None)
print("Total Keypoints without nonmaxSuppression:{}".format(len(kp)) )
# 2.6绘制为进行非极大值抑制的结果
img3= cv.drawKeypoints(img,kp,None,color=(0,0,255))
#3绘制图像
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img2[:,:,::-1])
axes[0].set_title("jiaru")
axes[1].imshow(img3[:,:,::-1])
axes[1].set_title("nonw")
plt.show( )
2.ORB算法
(1)原理
ORB(Oriented FAST and Rotated BRIEF)是 OpenCV 中一种轻量级的特征点检测与描述算法,由 Ethan Rublee 等人在 2011 年提出。它结合了 FAST 角点检测的速度优势和 BRIEF 描述符的简洁性,并通过旋转不变性优化,成为实时计算机视觉任务(如 SLAM、目标跟踪)的理想选择
ORB 的核心组件
ORB 算法主要由三部分组成:
1. FAST 角点检测
- 快速角点筛选:使用 FAST 算法检测角点(见上一轮对话),通过检查像素周围 16 个点中是否有连续的 n 个点(通常 n=9)灰度值明显高于或低于中心点。
- 非极大值抑制:保留局部响应值最大的角点,避免角点聚集。
- 关键点质量排序:基于 Harris 响应值对角点进行排序,选择前 N 个高质量角点。
2. BRIEF 描述符
- 二进制描述符:BRIEF(Binary Robust Independent Elementary Features)通过比较关键点邻域内随机点对的灰度值生成二进制串(如 128 位、256 位)。
- 示例:若点对(p1,p2)中p1的灰度值大于p2,则对应位为 1,否则为 0。
- 优点:存储效率高(仅需几字节),匹配速度快(使用汉明距离)。
- 缺点:不具备旋转不变性,对图像旋转敏感。
3. 旋转不变性优化
- 主方向计算:使用灰度质心法(Intensity Centroid)为每个关键点分配方向。
质心C的坐标为:
C=(∑I(x,y)∑x⋅I(x,y),∑I(x,y)∑y⋅I(x,y))
方向角θ为从关键点O到质心C的向量角度:
θ=arctan2(m01,m10)
其中mpq=∑x∑yxpyqI(x,y)是图像矩。 - 旋转 BRIEF:根据计算的方向θ,将 BRIEF 采样模式旋转θ角度,使描述符具有旋转不变性。
ORB 的特点与优势
优点
- 速度极快:比 SIFT 快 100 倍,比 SURF 快 10 倍,适合嵌入式设备或实时应用。
- 内存占用小:二进制描述符仅需几十字节,远低于 SIFT 的 128 字节。
- 旋转不变性:通过灰度质心法和旋转 BRIEF 解决了 BRIEF 的旋转敏感问题。
- 抗噪性强:对光照变化和小范围变形有较好的鲁棒性。
- 开源免费:无需专利授权,可商业使用。
缺点
- 尺度不变性有限:仅支持有限的尺度范围(通过金字塔分层实现),不如 SIFT/SURF。
- 描述符区分性较弱:在复杂场景下,匹配准确率略低于浮点型描述符(如 SIFT)。
(2)实现
1.实例化ORB
orb = cv2.xfeatures2d.orb_create(nfeatures)
nfeatures:特征点的最大数量
2. 利用orb.detectAndCompute()检测关键点并计算
kp,des = orb.detectAndCompute(gray,None)
gray:进行关键点检测的图片,灰度图
3.举例
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
#1图像读取
img = cv.imread('./image/1.jpg')
# 2 0RB角点检测
# 2.1 实例化ORB对象
orb =cv.ORB_create(nfeatures=500)
# 2.2 检测关键点,并计算特征描述符
kp,des = orb.detectAndCompute(img,None)
print(des.shape)
#3 将关键点绘制在图像上
img2 = cv.drawKeypoints(img,kp,None,color=(0,0,255),flags=0)
# 4. 绘制图像
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img2[:,:,::-1])
plt.xticks([]),plt.yticks([])
plt.show()