OpenCV高端操作——特征检测(附案例实战)

harris角点检测

简介:

Harris角点检测算法是一种常用的计算机视觉算法,用于检测图像中的角点。该算法通过计算图像中每个像素的局部自相关矩阵,来判断该像素是否为角点。

基本思想:

使用一个固定的小窗口在图像上进行任意方向的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化(sobel算子),那么我们可以认为该窗口中存在角点。

python 复制代码
cv2.cornerHarris(src, blockSize, ksize, k)

参数介绍:

src:

输入图像(单通道(灰度图)浮点 / 8 位)

blockSize:

角点检测时的邻域大小 (比如 blockSize=2 表示以当前像素为中心的 2x2 区域)。值越大,检测越稳定,但角点定位越粗糙。

ksize:

Sobel 算子的孔径大小(卷积核尺寸),必须是奇数(Sobel 算子要求)。值越大,对边缘的敏感度越低,角点检测越平滑。

k:

Harris 检测的**自由参数,**控制角点检测的 "严格程度":k 越小,检测出的角点越多(容易包含伪角点);k 越大,检测出的角点越少(更严格)。

返回值:

输出的角点响应图 (与输入图像同尺寸的单通道浮点数组),响应值越大,表示该像素点是角点的概率越高;响应值为负,通常表示该点是边缘或平坦区域。

python 复制代码
img = cv2.imread('../data/shan.jpeg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
dst = cv2.cornerHarris(gray,4,3,0.04)

img[dst > 0.01*dst.max()] = [0,0,255]
#这里通过对角点响应进行阈值处理,标记出检测到的角点。
#0.05 *dst.max()是一个阈值,大于这个值的像素点会被标记为红色。
cv2.imshow('img',img)
cv2.waitKey(0)

特征提取sift

简介:

SIFT(Scale Invariant Feature Transform)尺度不变特征变换。SIFT特征具有对旋转、尺度缩放、亮度变化等保持不变性,是一种非常稳定的局部特征。

特点:

1、图像的局部特征,对旋转、尺度缩放、亮度变化保持不变,对视角变化、仿射变换、噪声也保持一定程度的稳定性。

2、独特性好,信息量丰富,适用于海量特征库进行快速、准确的匹配。

3、多量性,即使是很少几个物体也可以产生大量的SIFT特征

4、高速性,经优化的SIFT匹配算法甚至可以达到实时性

5、扩招性,可以很方便的与其他的特征向量进行联合。

首先要通过以下代码来创建一个实例

python 复制代码
cv2.SIFT_create()

常用方法介绍:

python 复制代码
sift.detect(src, mask=None)

参数介绍:

src:

输入的图像,必须是灰度图(单通道),支持 8 位无符号整数(uint8)或 32 位浮点型(float32)。

mask:

尺寸和输入图像一致的 8 位单通道图,非零区域表示需要检测关键点的区域,零区域会被忽略。常用 None(检测整张图)。

返回属性:

返回值是 cv2.KeyPoint(关键点) 对象组成的列表,每个 KeyPoint 对象包含以下核心属性:

pt:关键点的像素坐标 (x, y)

size:关键点的尺度(代表该点在哪个尺度下被检测到,值越大对应越大的特征)

angle:关键点的主方向。

response:关键点的响应值(值越大,该关键点的显著性越高)

python 复制代码
cv2.drawKeypoints(img, keypoints, outImage, color=None, flags=0)

参数介绍:

img:

输入原始图像,可以是彩色图(3 通道)或灰度图(单通道),绘制后的关键点会叠加在这张图上。

keypoints:

关键点列表

outImage:

输出图像(提前创建的画布),若为None则OpenCV 会自动创建一个和 img 尺寸、类型相同的图像作为输出画布,无需手动初始化。

color:

元组(B, G, R) 或 None,格式为 (蓝,绿,红) 的整数元组(取值 0~255),None 时自动用随机颜色。

flags:

绘制模式,决定只画位置、还是画尺度 / 方向

参数选择:

cv2.DRAW_MATCHES_FLAGS_DEFAULT:仅绘制关键点的位置(小实心圆点),不显示尺度和方向。

cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS:绘制完整信息:1. 圆圈大小 = 关键点尺度(size)2. 线段 = 关键点方向(angle)3. 圆心 = 关键点位置(pt)

python 复制代码
keypoints, descriptors = sift.compute(src, keypoints)

参数介绍:

src:

输入的图像,必须是灰度图(单通道),支持 8 位无符号整数(uint8)或 32 位浮点型(float32)

keypoints:

关键点列表

返回值介绍:

keypoints:

过滤后的关键点列表(部分关键点因位置 / 尺度异常无法计算描述子,会被过滤,返回的列表是有效关键点)

descriptors:

描述符,格式为 (N, 128) 的浮点型数组(N 是有效关键点数量,128 是 SIFT 描述子的固定维度),每个行向量对应一个关键点的特征描述。

python 复制代码
keypoints, descriptors = sift.detectAndCompute(src, mask=None)

完成 "关键点检测 + 描述子计算",是 detect() + compute() 的合并版

参数介绍:

src:

输入的图像,必须是灰度图(单通道),支持 8 位无符号整数(uint8)或 32 位浮点型(float32)。

mask:

尺寸和输入图像一致的 8 位单通道图,非零区域表示需要检测关键点的区域,零区域会被忽略。常用 None(检测整张图)。

返回值:

keypoints

cv2.KeyPoint 对象列表包含所有检测到的关键点,每个对象有 pt(坐标)、size(尺度)、angle(方向)等属性;

descriptors

特征描述子数组SIFT 中为 (N, 128) 形状的 float32 数组(N 是关键点数量,128 是固定维度);若未检测到关键点,返回 None

接下来进行描述符匹配

python 复制代码
#实例化匹配器
flann = cv2.FlannBasedMatcher()
#使用k近邻匹配(des1中的每个描述符与des2中的每个描述符最近两个描述符进行匹配)
matches = flann.knnMatch(queryDescriptors, trainDescriptors, k)

flann.knnMatch(queryDescriptors, trainDescriptors, k)参数介绍:

queryDescriptors:

查询描述符(待匹配的特征)

trainDescriptors:

训练描述符(数据库中的特征)

k:

要找的近邻数量,为每个 des1des2 中最相似的 k 个匹配项,

示例:

python 复制代码
img = cv2.imread('../data/shan.jpeg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
sift = cv2.SIFT_create() #sift对象
kp = sift.detect(gray)
#kp.pt:关键点的(x,y)
#坐标。
#kp.size:关键点的大小(尺度)
#kp.angle:关键点的方向。
#kp.response:关键点的响应值。
#kp.octave:关键点所在的金字塔层级。
#查找关键点
# drawKeypoints(image, keypoints, outImage, color=None, flags=None)
#image:原始图片
#keypoints:从原图中获得的关键点,这也是画图时所用到的数据
#outputimage:输出图像,可以是原始图片,也可以是None
#color:颜色设置,通过修改(b,g,r)的值,更改画笔的颜色,b=蓝色,g=绿色,r=红色。
#fags:绘图功能的标识设置
gray_sift = cv2.drawKeypoints(img,kp,None,flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('img',gray_sift)
cv2.waitKey(0)

#使用sift.compute()计算关键点描述符,方便后期的特征匹配
kp,des = sift.compute(img,kp)
print(np.array(kp).shape,des.shape)
# 输出关键点的形状和描述符的形状。
#np.array(kp).shape 表示关键点的数量和属性。
# des.shape 表示描述符的数量和属性。

指纹识别案例实战

指纹验证案例,将两个源图像与模板图像进行特征提取,来判断模板图像与源图像验证是否匹配。

源图像:

模板图像:

python 复制代码
import cv2

def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)

def verification(src,model):
    # 创建SIFT特征提取器
    sift = cv2.SIFT_create()
    # 检测关键点和计算描述符(特征向量) 源图像
    kp1,des1 = sift.detectAndCompute(src,None)
    # 检测关键点和计算描述符 模板图像
    kp2,des2 = sift.detectAndCompute(model,None)
    # 创建FLANN匹配器
    flann = cv2.FlannBasedMatcher()
    #使用k近邻匹配(des1中的每个描述符与des2中的每个描述符最近两个描述符进行匹配)
    matches = flann.knnMatch(des1,des2,k=2)
#distance:匹配的特征点描述符的欧式距离,数值越小也就说明俩个特征点越相近。
##queryIdx:测试图像的特征点描述符的下标(第几个特征点描述符),同时也是描述符对应特征点的下标。/k13.ri/
#trainIdx:样本图像的特征点描述符下标,同时也是描述符对应特征点的下标。

    # 进行比较筛选
    ok =[]
    for m,n in matches:
        #根据Lowe's比率测试,选择最佳匹配
        if m.distance < 0.80*n.distance:
            ok.append(m)
    # 统计通过筛选的匹配数量
    num = len(ok)
    if num >= 500:
        result = '认证通过'
    else:
        result = '认证失败'
    return result

if __name__ == '__main__':
    src1 = cv2.imread('../data/src1.bmp')
    cv2.imshow('src1',src1)
    src2 = cv2.imread('../data/src2.bmp')
    cv2.imshow('src2',src2)
    model = cv2.imread('../data/model.bmp')
    cv2.imshow('model',model)

    result1 = verification(src1,model)
    result2 = verification(src2,model)
    print("src1的结果为",result1)
    print("src2的结果为",result2)
    cv2.waitKey(0)
相关推荐
RuiBo_Qiu2 小时前
LLM的神经网络之谜: 神经网络是简单的线性计算加非线形激活的堆叠
人工智能·深度学习·神经网络
金融小师妹2 小时前
基于多因子定价模型解析:美元强势与利率预期重构驱动的金价8连跌机制
大数据·人工智能·svn·能源
赵庆明老师2 小时前
08-AI论文创作:辅助文献阅读
人工智能
QYR_Jodie2 小时前
全球聚硫醇固化剂市场:2026-2032年CAGR7.0%,2032年规模2.4亿美元
大数据·人工智能
AI营销快线2 小时前
AI营销如何破解增长瓶颈?原圈科技以智能体驱动高效增长
大数据·人工智能
小柒777772 小时前
PEFT(Parameter-Efficient Fine-Tuning)---LoRa方法
人工智能·深度学习·语言模型
HIT_Weston2 小时前
20、【Agent】【OpenCode】源码构建(依赖安装)
人工智能·agent·opencode
记忆张量MemTensor2 小时前
AI 数据迁移指南|Claude 靠提示词搬家,MindDock 一键完整备份记忆
人工智能·python·开源·github·浏览器
爱打代码的小林2 小时前
OpenCV 实战:为视频添加椒盐噪声并实现中值滤波去噪
人工智能·opencv·计算机视觉