sift+bow+svm

本文概述

利用SIFT特征进行简单的花朵识别

SIFT算法的特点有:

  1. SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性;
  2. SIFT算法提取的图像特征点数不是固定值,维度是统一的128维。
  3. 独特性(Distinctiveness)好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配;
  4. 多量性,即使少数的几个物体也可以产生大量的SIFT特征向量;
  5. 高速性,经优化的SIFT匹配算法甚至可以达到实时的要求;
  6. 可扩展性,可以很方便的与其他形式的特征向量进行联合。

KMeans聚类获得视觉单词,构建视觉单词词典

现在得到的是所有图像的128维特征,每个图像的特征点数目还不一定相同(大多有差异)。现在要做的是构建一个描述图像的特征向量,也就是将每一张图像的特征点转换为特征向量。这儿用到了词袋模型,词袋模型源自文本处理,在这儿用在图像上,本质上是一样的。词袋的本质就是用一个袋子将所有维度的特征装起来,在这儿,词袋模型的维度需要我们手动指定,这个维度也就确定了视觉单词的聚类中心数。

支持向量机

算法流程:

  1. SIFT提取每幅图像的特征点:

     import csv
     import os
     from sklearn.cluster import KMeans
     import cv2
     import numpy as np
    
    
     def knn_detect(file_list,cluster_nums, randomState = None):
         content = []
         input_x = []
         labels=[]
         features = []
         count = 0
         csv_file = csv.reader(open(file_list,'r'))
         for line in csv_file:
             if(line[2] !='label'):
                 subroot = 'F:\\train\\g' + str(line[2])
                 filename =os.path.join(subroot, line[1])
                 sift = cv2.xfeatures2d.SIFT_create(200)
                 img = cv2.imdecode(np.fromfile(filename,dtype=np.uint8),-1)
                 if img is not None:
    
                     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                     kpG, desG = sift.detectAndCompute(gray, None)#关键点描述符
    
                     if desG is None:
                         continue 
                     print(count)
                     count+=1
                     ll = np.array(line[2]).flatten()
                     labels.append(ll)
                     features.append(desG) 
                     input_x.extend(desG)
         print(len(input_x))
         return features,labels,input_x
    
    
    
     des_list = []
     labelG = []
     input_x1 = []
     des_list,labelG,input_x1 = knn_detect('E:\\py\\train.csv',50)
    
     festures_test = []
     labels_test  = []
     input_x2 = []
     features_test,labels_test,input_x2 = knn_detect('E:\\py\\test.csv',50)

结果截图:

  1. 保存中间变量:

     import numpy as np
     import matplotlib.pyplot as plt
     import pandas as pd
     import pickle
    
     output = open('input_x2.pkl', 'wb')
     pickle.dump(input_x2, output)
     output.close()
    
     output = open('features_test.pkl', 'wb')
     pickle.dump(features_test, output)
     output.close()
    
     output = open('labels_test.pkl', 'wb')
     pickle.dump(labels_test, output)
     output.close()
    
     output = open('input_x22.pkl', 'wb')
     pickle.dump(input_x2, output,protocol=2)
     output.close()
  2. 将图像特征点映射到视觉单词上,得到图像特征:

     df=open('input_x2.pkl','rb')#注意此处是rb
     #此处使用的是load(目标文件)
     input_x1=pickle.load(df)
     df.close()
     kmeans = KMeans(n_clusters = 50, n_jobs =4,random_state = None).fit(input_x1)
     centers = kmeans.cluster_centers_
  3. 将图像特征点映射到视觉单词上,得到图像的特征向量:

     def des2feature(des,num_words,centures):
     '''
     des:单幅图像的SIFT特征描述
     num_words:视觉单词数/聚类中心数
     centures:聚类中心坐标   num_words*128
     return: feature vector 1*num_words
     '''
     img_feature_vec=np.zeros((1,num_words),'float32')
     for i in range(des.shape[0]):
         feature_k_rows=np.ones((num_words,128),'float32')
         feature=des[i]
         feature_k_rows=feature_k_rows*feature
         feature_k_rows=np.sum((feature_k_rows-centures)**2,1)
         index=np.argmax(feature_k_rows)
         img_feature_vec[0][index]+=1
     return img_feature_vec
    
     def get_all_features(des_list,num_words):
     # 获取所有图片的特征向量
     allvec=np.zeros((len(des_list),num_words),'float32')
     for i in range(len(des_list)):
         if des_list[i].any()!=None:
             allvec[i]=des2feature(centures=centers,des=des_list[i],num_words=num_words)
     return allvec
    
     df=open('des_list.pkl','rb')#注意此处是rb
     #此处使用的是load(目标文件)
     des_list=pickle.load(df)
     df.close()
     a =get_all_features(des_list,50)
     print(len(a))
     output = open('特征向量.pkl', 'wb')
     pickle.dump(a, output)
     output.close()
  4. svm训练,查看准确率:

     import numpy as np
     import matplotlib.pyplot as plt
     import pandas as pd
     from sklearn.preprocessing import StandardScaler
     sc = StandardScaler()
     X_train = sc.fit_transform(a)
     X_test = sc.fit_transform(b)
    
     from sklearn.svm import SVC
     classifier = SVC( random_state = 0)
     classifier.fit(X_train,labelG)
    
     y_pred = classifier.predict(X_test)
    
     print(classifier.score(X_test,labels_test))
     from sklearn.metrics import classification_report
     print(classification_report(labels_test,y_pred))

    结果截图:

猜你喜欢

转载自www.cnblogs.com/gzyc/p/11221963.html
BOW
svm