一、算法背景介绍
Lowe于2000年提出了SIFT算法,并于2004年加以完善和改进,SIFT特征对图像旋转、平移、缩放、亮度变化能够保持良好的不变性,且其独特性好,信息量较为丰富,得到了广泛的应用,但其提取计算量较大,效率较低,因此Bay等人提出了SURF算法,在保证特征点数量的情况下,提高了效率。
SURF算法首先构建Hessian矩阵,然后构建尺度空间(SIFT算法则使用DOG),其在构建图像金字塔时原始图像大小保持不变,只改变滤波器大小,然后精确定位特征点并确定其主方向,最后生成特征点描述子。
此外,SURF算法得到的特征向量维度为64,而SIFT得到的是128维向量。
二、实现代码
下述代码计算images_folder文件夹下的所有图片的SURF特征,然后将图片与特征向量其保存到指定文件夹
#-*-coding:utf-8-*-
import cv2
import numpy as np
from sklearn.cluster import KMeans
import sys
import os
path = sys.path[0] + os.sep
def feature_extract(images_folder, draw_folder):
featureSum = 0
for filename in os.listdir(images_folder):
if '.jpg' in filename:
filepath + images_folder + filename
drawpath = draw_folder + filename
else:
continue
img = cv2.imread(filepath)
filename = filepath.split(os.sep)[-1].split('.')[0]
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# set Hessian threshold
detector = cv2.xfeatures2d.SURF_create(2000)
# find keypoints and descriptors directly
kps, des = detector.detectAndCompute(gray, None)
img = cv2.drawKeypoints(image=img, outImage=img, keypoints=kps, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, color=(255, 0, 0))
feature_name = images_folder + 'features%s%s.feature'%(os.sep, filename)
try:
np.savetxt(feature_name, des, fmt='%.5e') # 保存特征向量
# feature = np.loadtxt(feature_folder + filename) # 加载特征向量
# cv2.imwrite(drawpath, img) # 保存绘制了SURF特征的图片
except:
continue
featureSum += len(kps)
print featureSum
def main():
images_folder = path + 'images' + os.sep
draw_folder = path + 'results' + os.sep + 'drawImages' + os.sep
feature_extract(images_folder, draw_folder)
以上,欢迎交流~