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:
要找的近邻数量,为每个 des1 找 des2 中最相似的 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)
