来源:
尺度不变特征转换(Scale-invariant feature transform或SIFT)算法是一种特征提取的方法。它在尺度空间中寻找极值点,并提取出其位置、尺度、旋转不变量,并以此作为特征点并利用特征点的邻域产生特征向量。SIFT算法对于光线、噪声、和微小视角改变的容忍度相当高,且对于部分遮挡的物体也有较高的识别相率。
SIFT算法适合于识别旋转度达60度的平面形状,或是旋转度达到20度的三维物体。
SIFT算法对模糊的图像和边缘平滑的图像,检测出的特征点过少,对圆更是无能为力
import os
import warnings
import numpy as np
import cv2 as cv
import hmmlearn.hmm as hl
warnings.filterwarnings('ignore',category=DeprecationWarning)
np.seterr(all='ignore')
def search_objects(directory):
directory = os.path.normpath(directory)
if not os.path.isdir(directory):
raise IOError("the directory '"+ directory + \
"' doesn't exist")
objects ={}
for curdir ,subdirs, files in os.walk(directory):
for jpeg in (file for file in files if file.endswith('.jpg')):
path = os.path.join(curdir,jpeg)
label = path.split(os.path.sep)[-2]
if label not in objects:
objects[label]=[]
objects[label].append(path)
return objects
train_objects=search_objects('data/objects/training')
print(train_objects)
train_x, train_y =[],[]
for label, filenames in train_objects.items():
descs = np.array([])
for filename in filenames:
image = cv.imread(filename)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
#调整大小
h,w =gray.shape[:2]
f =200/min(h,w)
gray = cv.resize(gray,None,fx=f,fy=f)
star=cv.xfeatures2d.StarDetector_create()
keypoints = star.detect(gray)
sift = cv.xfeatures2d.SIFT_create()
_,desc = sift.compute(gray,keypoints)
if len(descs)==0:
descs=desc
else:
descs=np.append(descs,desc,axis=0)
train_x.append(descs)
train_y.append(label)
models={}
for descs, label in zip(train_x,train_y):
model= hl.GaussianHMM(n_components=4,
covariance_type='diag',
n_iter=1000
)
models[label]=model.fit(descs)
test_objects=search_objects('data/objects/testing')
print(train_objects)
test_x, test_y, test_z=[],[],[]
for label, filenames in test_objects.items():
test_z.append([])
descs = np.array([])
for filename in filenames:
image = cv.imread(filename)
test_z[-1].append(image)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
#调整大小
h,w =gray.shape[:2]
f =200/min(h,w)
gray = cv.resize(gray,None,fx=f,fy=f)
star=cv.xfeatures2d.StarDetector_create()
keypoints = star.detect(gray)
sift = cv.xfeatures2d.SIFT_create()
_,desc = sift.compute(gray,keypoints)
if len(descs)==0:
descs=desc
else:
descs=np.append(descs,desc,axis=0)
test_x.append(descs)
test_y.append(label)
pred_test_y=[]
for descs in test_x:
best_score, best_label =None,None
for label, model in models.items():
score=model.score(descs)
if(best_score is None)or(best_score<score):
best_score, best_label = score,label
pred_test_y.append(best_label)
i=0
for label,pred_label,images in zip(test_y,pred_test_y,test_z):
for image in images:
i+=1
cv.imshow("{}-{} {} {}".format(i,label,'=='
if label == pred_label else '!=',pred_label),image)
cv.waitKey()