#获取图片的局部特征--sift特征
def get_feature(img):
# sift = cv2.SIFT_create()
sift = cv2.xfeatures2d.SIFT_create()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kp = sift.detect(gray, None)
sift_val_back = sift.compute(gray, kp)[1]
[r,c]=sift_val_back.shape
combine = sift_val_back
#获取词典--kmeans聚类--1800
def get_wordsdict(img,SeedNum):
Combine = []
for i in img:
combine= get_feature(i)
# print(combine.shape)
Combine.append(combine)
Combine = np.vstack(Combine)
print(Combine.shape)
# kmeans 聚类, bow[i] 为每个特征属于哪个组的, cord[i] 为各个中心组分别是第几号的
# distance[i] 为各个特征与所属的中心点的距离差
model = KMeans(n_clusters=SeedNum, random_state=9)
model.fit_transform(Combine)
#保存码本
#joblib.dump(model, 'KMeans.pkl')
centers = model.cluster_centers_
np.save('centers.npy',centers)
print(centers.shape)#(1800, 128)
traindata, labels, paths = get_data('./image')#获取训练集‘image’下的所有文件
get_wordsdict(traindata,1800)#使用kmeans进行聚类--聚类中心个数设置为1800--结果保存到centers.npy文件中(存放聚类的中心点)
#返回的为BOF向量--未做tf-idf处理
#L为1维的list--len(L)=1800
def BOF(img):
features = get_feature(img) #输入一张图像 返回sift特征 features.shape = (X, 128) 不同图片生成的特征个数(X)不同
centers = np.load('./centers.npy') # 聚类的中心点 centers.shape = (1800, 128)
wordCnt = 1800 #聚类中心个数 码本大小
L = [0 for j in range(1800)] #initial BOF向量 --1800长度的list
#统计图片的features中 聚类中心出现的次数
for i in range(0, features.shape[0]):
#第i张图片的特征点
fi = features[i]
diffMat = np.tile(fi, (wordCnt, 1)) - centers
#axis=1按行求和,即求特征到每个中心点的距离
sqSum = (diffMat**2).sum(axis=1)
dist = sqSum**0.5
#升序排序
sortedIndices = dist.argsort()
#取出最小的距离,即找到最近的中心点
idx = sortedIndices[0]
#该中心点对应+1
L[idx] += 1
# print("get_single_bof")
return L
def VLAD(img):
combine = get_feature(img)
centers = np.load('./centers.npy')#聚类的中心点
L = [0 for j in range(1800)]
for i in range(0, combine.shape[0]):
#第i张图片的特征点
fi = combine[i]
diffMat = np.tile(fi, (1800, 1)) - centers
#axis=1按行求和,即求特征到每个中心点的距离
sqSum = (diffMat**2).sum(axis=1)
dist = sqSum**0.5
#升序排序
sortedIndices = dist.argsort()
#取出最小的距离,即找到最近的中心点
idx = sortedIndices[0]
#该中心点对应+1
L[idx] += dist[idx]
# print("=======get_sigle_feature_finish======")
return l2_normalize(L)
# return L
import numpy as np
import math
#计算公式 hj = log(n/fj)
# ---n为训练集所有图片数量
# ---fj为第j个聚类特征在训练集中出现的图片数量
# ---hj为j向量的权重
def get_tf_idf():
train_bof = np.load('./train_BOF.npy')
# print(train_bof.shape) #(946, 1800)
N = train_bof.shape[0]#训练集中的图片总数
f = [0 for j in range(1800)] #生成码本的 权重向量
#计算每个特征出现的图片次数
for i in range(train_bof.shape[0]):
for j in range(train_bof.shape[1]):
if(train_bof[i][j]!=0):
f[j]+=1;
# print(len(f)) #1800
for i in range(len(f)):
f[i]=math.log(N/f[i])
# print(f)
np.save("bof_weight.npy",f)
怎么开始cv了哈哈哈
课设