SIFT(尺度不变特征变换)含代码

sift具体过程参考:
https://hanhandi.blog.csdn.net/article/details/105640230?spm=1001.2014.3001.5506

SIFT的特征点筛选目的:寻找在不同尺度空间下的极值点,保证这些特征点在放大或者缩小的条件下均存在。
SIFT(尺度不变特征变换)含代码_第1张图片
要搞清楚高斯核的原理的话,把下面这篇博文认认真真看一遍就可以了,链接如下:
https://blog.csdn.net/u013066730/article/details/123112159

但其实对我们实现sift功能没什么帮助,只是更好的理解算法的过程。毕竟像opencv这种主打的就是开源高效。

detector =cv2.SIFT_create()
通过上面代码我们便直接创建一个sift实例。
考虑到sift算法包括了很多函数,大家可以参考:

cv2.SIFT_create()

创建sift对象,官方文档:https://docs.opencv.org/4.5.3/d7/d60/classcv_1_1SIFT.html

sift = cv2.SIFT_create(nfeatures=0, nOctaveLayers=3, contrastThreshold=0.04, edgeThreshold=10, sigma=1.6)

参数:
nfeatures: 需要保留的特征点的个数,特征按分数排序(分数取决于局部对比度)
nOctaveLayers:每一组高斯差分金字塔的层数,sift论文中用的3。高斯金字塔的组数通过图片分辨率计算得到
contrastThreshold: 对比度阈值,用于过滤低对比度区域中的特征点。阈值越大,检测器产生的特征越少。 (sift论文用的0.03,nOctaveLayers若为3, 设置参数为0.09,实际值为:contrastThreshold/nOctaveLayers)
edgeThreshold:用于过滤掉类似图片边界处特征的阈值(边缘效应产生的特征),注意其含义与contrastThreshold不同,即edgeThreshold越大,检测器产生的特征越多(过滤掉的特征越少);sift论文中用的10;
sigma:第一组高斯金字塔高斯核的sigma值,sift论文中用的1.6。 (图片较模糊,或者光线较暗的图片,降低这个参数)
descriptorType:特征描述符的数据类型,支持CV_32F和CV_8U

返回值:sift对象(cv2.Feature2D对象)
cv2.Feature2D.detect()

检测特征关键点,官方文档:https://docs.opencv.org/4.5.3/d0/d13/classcv_1_1Feature2D.html#a8be0d1c20b08eb867184b8d74c15a677

keypoints = cv2.Feature2D.detect(image, mask)
参数:
image:需要检测关键点的图片
mask:掩膜,为0的区域表示不需要检测关键点,大于0的区域检测
返回值:
keypoints:检测到的关键点
cv2.Feature2D.compute()

生成特征关键点的描述符,官方文档:https://docs.opencv.org/4.5.3/d0/d13/classcv_1_1Feature2D.html#a8be0d1c20b08eb867184b8d74c15a677

keypoints, descriptors = cv.Feature2D.compute(image, keypoints)
参数:
image:需要生成描述子的图片
keypoints: 需要生成描述子的关键点
返回值:
keypoints:关键点(原始关键点中,不能生成描述子的关键点会被移除;)
descriptors:关键点对应的描述子

cv2.Feature2D.detectAndCompute()

检测关键点,并生成描述符,是上面detect()和compute()的综合

keypoints, descriptors = cv.Feature2D.detectAndCompute(image, mask)
cv2.drawKetpoints()

绘制检测到的关键点,官方文档:https://docs.opencv.org/4.5.3/d4/d5d/group__features2d__draw.html#ga5d2bafe8c1c45289bc3403a40fb88920

outImage = cv2.drawKeypoints(image, keypoints, outImage, color, flags)
参数:
image:检测关键点的原始图像
keypoints:检测到的关键点
outImage:绘制关键点后的图像,其内容取决于falgs的设置
color:绘制关键点采用的颜色
flags:
cv2.DRAW_MATCHES_FLAGS_DEFAULT:默认值,匹配了的关键点和单独的关键点都会被绘制
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS: 绘制关键点,且每个关键点都绘制圆圈和方向
cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG:
cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS:只绘制匹配的关键点,单独的关键点不绘制

	**keypoint**

https://docs.opencv.org/4.5.3/d2/d29/classcv_1_1KeyPoint.html#aea339bc868102430087b659cd0709c11

上述检测到的keypoint,在opencv中是一个类对象,其具有如下几个属性:
angle: 特征点的方向,值在0-360
class_id: 用于聚类id,没有进行聚类时为-1
octave: 特征点所在的高斯金差分字塔组
pt: 特征点坐标
response: 特征点响应强度,代表了该点时特征点的程度(特征点分数排序时,会根据特征点强度)
size:特征点领域直径

代码如下:

#sift特征提取
#算法的实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向

import cv2
import numpy as np

inputImgfile = 'red.png'
outputImgfile = 'red_sift.png'
outputfeature='red_sift.txt'

# feature number
featureSum = 0 
img = cv2.imread(inputImgfile)
cv2.imshow("chuan",img)

gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) 
detector =cv2.SIFT_create() #实例化一个sift
# key point
kps , des = detector.detectAndCompute(gray,None) 
# drawing key points 
img=cv2.drawKeypoints(image=img, outImage=gray, keypoints=kps,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, color=(51, 163, 236)) 
cv2.imwrite(outputImgfile,img)
# save key point

np.savetxt(outputfeature ,des , fmt='%.2f') 
featureSum += len(kps) 
cv2.imshow('result',img)
 
print('kps:' + str(featureSum))

while 1:
 key = cv2.waitKey(1)
 if key>0:
   break
cv2.destroyAllWindows()

你可能感兴趣的:(python,计算机视觉,opencv,python)