使用OpenCV:图像特征提取和描述

一.角点特征

图像的特征

图像的特征是指能够描述图像本质属性、区分不同图像的视觉信息或抽象属性,是计算机视觉、图像处理等领域分析和理解图像的基础。这些特征可以从多个维度进行分类和解读,具体如下:

基于视觉感知的底层特征

这类特征是人类视觉系统能直接观察到的基本属性,也是计算机处理图像时首先提取的信息。

  1. 颜色特征

    • 描述图像中像素的颜色组成和分布,是最直观的特征之一。
    • 常见表示方式:
      • 颜色空间(如 RGB、HSV、Lab 等):不同空间对颜色的描述侧重不同,例如 HSV 更符合人类对色彩(Hue)、饱和度(Saturation)、明度(Value)的感知。
      • 颜色直方图:统计图像中每种颜色出现的频率,可用于快速比较图像的色调分布(如红色主导的图像 vs 蓝色主导的图像)。
    • 应用:图像检索(如按 “红色花朵” 搜索)、肤色检测、产品颜色分类等。
  2. 纹理特征

    • 描述图像中像素的排列规律,体现物体表面的粗糙、平滑、条纹、斑点等质感。
    • 常见类型:
      • 规则纹理:如布料的格子、砖墙的缝隙,具有周期性重复模式。
      • 不规则纹理:如树皮、云朵,无明显重复规律但有整体质感。
    • 提取方法:通过灰度共生矩阵(统计像素间灰度关系)、LBP 算子(局部二值模式)等量化。
    • 应用:区分布料(丝绸 vs 牛仔)、识别卫星图像中的土地类型(森林 vs 沙漠)。
  3. 形状特征

    • 描述图像中物体的轮廓或几何形态,如圆形、方形、不规则曲线等。
    • 关键属性:
      • 轮廓:物体边缘的连续线条(如苹果的弧形轮廓)。
      • 面积、周长、长宽比:量化形状的大小和比例(如邮票的 “狭长形”)。
      • 矩特征:通过数学计算描述形状的对称性、中心位置等(如正三角形的中心对称特征)。
    • 应用:工业质检(检测零件是否为标准圆形)、手写数字识别(区分 “0” 和 “6” 的形状差异)。
  4. 空间分布特征

    • 描述图像中像素或物体的位置关系,如 “上下”“左右”“包围” 等。
    • 示例:一幅 “太阳在山顶上方” 的图像中,太阳与山的 “上下分布” 就是关键空间特征。
    • 应用:场景理解(如 “教室” 场景中 “黑板在讲台上方” 的布局)、图像语义分割(标注物体间的位置关联)。

基于语义理解的高层特征

这类特征需要结合知识或上下文,反映图像的抽象含义,超越了底层视觉信息。

  1. 语义内容

    • 图像所表达的实际意义,如 “一只猫在沙发上睡觉”“城市夜景” 等。
    • 依赖底层特征的组合:例如 “猫” 的语义需要颜色(毛色)、形状(流线型身体、尖耳朵)、纹理(毛发质感)等底层特征共同支撑。
  2. 情感与风格特征

    • 图像传递的情感倾向(如温暖、压抑、欢快)或艺术风格(如油画、素描、卡通)。
    • 示例:梵高的《星月夜》通过扭曲的线条和强烈的色彩对比,体现 “狂放” 的风格特征;黑白老照片常带有 “怀旧” 的情感特征。

特征的提取与应用

  • 提取方式
    • 传统方法:手动设计算子(如 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 算法类似,但在响应函数计算和角点筛选上有差异:

  1. 预处理:转换为灰度图,高斯平滑降噪;
  2. 计算梯度:用 Sobel 算子计算Ix​,Iy​;
  3. 计算梯度协方差矩阵M
    (通常用高斯窗口加权求和,增强抗噪性);
  4. 计算特征值:对每个窗口的M计算特征值λ1​,λ2​;
  5. 响应函数计算:R=min(λ1​,λ2​);
  6. 阈值筛选:保留R≥threshold的点作为候选角点;
  7. 非极大值抑制:在局部邻域内保留响应值最大的点,避免冗余;
  8. 可选:角点排序与数量控制:按响应值降序排列,选择前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πσ21​e−(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+21​XTHX
其中X=(x,y,σ)T,∇D是梯度,H是 Hessian 矩阵。通过求解∇D(X)=0,得到精确极值点坐标,若其函数值(对比度)小于阈值(通常取 0.03),则剔除(低对比度点不稳定)。

2. 边缘点剔除

边缘点在一个方向上梯度变化大,另一个方向变化小,稳定性差。利用 Hessian 矩阵的主曲率判断是否为边缘点:
Hessian 矩阵H的主曲率α和β满足:

  • 迹Tr(H)=Dxx​+Dyy​
  • 行列式Det(H)=Dxx​Dyy​−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算法

特性SIFTSURF
提出时间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​∑y​xpyqI(x,y)是图像矩。
  • 旋转 BRIEF:根据计算的方向θ,将 BRIEF 采样模式旋转θ角度,使描述符具有旋转不变性。
ORB 的特点与优势
优点
  1. 速度极快:比 SIFT 快 100 倍,比 SURF 快 10 倍,适合嵌入式设备或实时应用。
  2. 内存占用小:二进制描述符仅需几十字节,远低于 SIFT 的 128 字节。
  3. 旋转不变性:通过灰度质心法和旋转 BRIEF 解决了 BRIEF 的旋转敏感问题。
  4. 抗噪性强:对光照变化和小范围变形有较好的鲁棒性。
  5. 开源免费:无需专利授权,可商业使用。
缺点
  1. 尺度不变性有限:仅支持有限的尺度范围(通过金字塔分层实现),不如 SIFT/SURF。
  2. 描述符区分性较弱:在复杂场景下,匹配准确率略低于浮点型描述符(如 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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值