2013-04-30 26 views
11

我遇到問題,我得到一組圖片並需要對這些圖片進行分類。將一組圖像分類爲

事情是,我真的沒有這些圖像的任何知識。所以我打算使用盡可能多的描述符,然後對這些描述符進行PCA處理,以便只識別對我有用的描述符。

我可以在很多數據點上進行監督學習,如果有幫助的話。但是,圖片之間有可能相互連接。這意味着從Image X到Image X + 1可能會有一個發展,儘管我希望能夠將每張圖片中的信息整理出來。

我的問題是:

  1. 使用Python時,我如何做到這一點最好的嗎? (我想首先在速度不成問題的情況下進行概念驗證)。我應該使用哪些庫?
  2. 是否有例子的圖像這樣的分類?使用一組描述符並通過PCA進行烹飪的示例?說實話,這部分對我來說有點嚇人。雖然我認爲python應該已經爲我做了這樣的事情。

編輯: 我發現我正在試圖走出這一個整潔套件:http://scikit-image.org/似乎有一些描述在那裏。有沒有辦法根據自己對目標分類的描述能力對特徵進行自動特徵提取和排名? PCA應該能夠自動排名。

編輯2: 我有我的數據存儲框架現在更精緻一點。我將使用Fat系統作爲數據庫。我將爲每個類的組合實例創建一個文件夾。因此,如果圖片屬於第1和第2類,將會有一個包含這些圖片的文件夾img12。這樣我可以更好地控制每個班級的數據量。

編輯3: 我找到了一個用於python的庫(sklearn)的例子,它執行某種我想要做的事情。它是關於識別手寫數字。我試圖將我的數據集轉換成我可以使用的東西。

這裏是我發現使用sklearn的例子:

import pylab as pl 

# Import datasets, classifiers and performance metrics 
from sklearn import datasets, svm, metrics 

# The digits dataset 
digits = datasets.load_digits() 

# The data that we are interested in is made of 8x8 images of digits, 
# let's have a look at the first 3 images, stored in the `images` 
# attribute of the dataset. If we were working from image files, we 
# could load them using pylab.imread. For these images know which 
# digit they represent: it is given in the 'target' of the dataset. 
for index, (image, label) in enumerate(zip(digits.images, digits.target)[:4]): 
    pl.subplot(2, 4, index + 1) 
    pl.axis('off') 
    pl.imshow(image, cmap=pl.cm.gray_r, interpolation='nearest') 
    pl.title('Training: %i' % label) 

# To apply an classifier on this data, we need to flatten the image, to 
# turn the data in a (samples, feature) matrix: 
n_samples = len(digits.images) 
data = digits.images.reshape((n_samples, -1)) 

# Create a classifier: a support vector classifier 
classifier = svm.SVC(gamma=0.001) 

# We learn the digits on the first half of the digits 
classifier.fit(data[:n_samples/2], digits.target[:n_samples/2]) 

# Now predict the value of the digit on the second half: 
expected = digits.target[n_samples/2:] 
predicted = classifier.predict(data[n_samples/2:]) 

print("Classification report for classifier %s:\n%s\n" 
     % (classifier, metrics.classification_report(expected, predicted))) 
print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted)) 

for index, (image, prediction) in enumerate(
     zip(digits.images[n_samples/2:], predicted)[:4]): 
    pl.subplot(2, 4, index + 5) 
    pl.axis('off') 
    pl.imshow(image, cmap=pl.cm.gray_r, interpolation='nearest') 
    pl.title('Prediction: %i' % prediction) 

pl.show() 
+0

到目前爲止您嘗試了什麼?顯示一些努力隊友。 – 2013-05-03 14:02:45

+0

我將編輯目前爲止完成的工作。 – tarrasch 2013-05-04 06:49:26

回答

8

您可以將圖片轉換爲像素矢量,並在該矢量上執行PCA。這可能比嘗試手動查找描述符更容易。您可以在Python中使用numPy和sciPy。 例如:

import scipy.io 
from numpy import * 
#every row in the *.mat file is 256*256 numbers representing gray scale values 
#for each pixel in an image. i.e. if XTrain.mat has 1000 lines than each line 
#will be made up of 256*256 numbers and there would be 1000 images in the file. 
#The following loads the image into a sciPy matrix where each row is a vector 
#of length 256*256, representing an image. This code will need to be switched 
#out if you have a different method of storing images. 
Xtrain = scipy.io.loadmat('Xtrain.mat')["Xtrain"] 
Ytrain = scipy.io.loadmat('Ytrain.mat')["Ytrain"] 
Xtest = scipy.io.loadmat('Xtest.mat')["Xtest"] 
Ytest = scipy.io.loadmat('Ytest.mat')["Ytest"] 
learn(Xtest,Xtrain,Ytest,Ytrain,5) #this lowers the dimension from 256*256 to 5 

def learn(testX,trainX,testY,trainY,n): 
    pcmat = PCA(trainX,n) 
    lowdimtrain=mat(trainX)*pcmat #lower the dimension of trainX 
    lowdimtest=mat(testX)*pcmat #lower the dimension of testX 
    #run some learning algorithm here using the low dimension matrices for example 
    trainset = []  

    knnres = KNN(lowdimtrain, trainY, lowdimtest ,k) 
    numloss=0 
    for i in range(len(knnres)): 
     if knnres[i]!=testY[i]: 
      numloss+=1 
    return numloss 

def PCA(Xparam, n): 
    X = mat(Xparam) 
    Xtranspose = X.transpose() 
    A=Xtranspose*X 
    return eigs(A,n) 

def eigs(M,k): 
    [vals,vecs]=LA.eig(M) 
    return LM2ML(vecs[:k]) 

def LM2ML(lm): 
    U=[[]] 
    temp = [] 
    for i in lm: 
     for j in range(size(i)): 
      temp.append(i[0,j]) 
     U.append(temp) 
     temp = [] 
    U=U[1:] 
    return U 

爲了你的形象進行分類,你可以使用k最近的鄰居。即您可以找到k個最近的圖像,並通過多數票對最近k個圖像標記您的圖像。例如:

def KNN(trainset, Ytrainvec, testset, k): 
    eucdist = scidist.cdist(testset,trainset,'sqeuclidean') 
    res=[] 
    for dists in eucdist: 
     distup = zip(dists, Ytrainvec) 
     minVals = [] 
    sumLabel=0; 
    for it in range(k): 
     minIndex = index_min(dists) 
     (minVal,minLabel) = distup[minIndex] 
     del distup[minIndex] 
     dists=numpy.delete(dists,minIndex,0) 
     if minLabel == 1: 
      sumLabel+=1 
     else: 
      sumLabel-=1 
     if(sumLabel>0): 
      res.append(1) 
     else: 
      res.append(0) 
    return res 
+0

你可以添加一個例子如何做到這一點? – tarrasch 2013-05-09 12:19:54

+0

我添加了一個例子,我希望它有幫助。 – 2013-05-09 20:44:18

+0

upvoted爲降維。 – tarrasch 2013-05-10 07:12:53

3

我知道我不能直接回答你的問題。但是,圖像差別很大:遙感,物體,場景,fMRI,生物內部,臉部等......如果您稍微縮小分類範圍並告訴我們,這將有所幫助。

你計算哪些描述符?我使用的大多數代碼(以及計算機視覺社區)都是在MATLAB中,而不是在python中,但我確定有類似的代碼可用(pycv模塊& http://www.pythonware.com/products/pil/)。嘗試使用預編譯麻省理工學院人員最先進的代碼的描述符基準:http://people.csail.mit.edu/jxiao/SUN/嘗試查看GIST,HOG和SIFT,這些都是非常標準的,取決於您想分析的內容:場景,對象或點。

+0

有沒有辦法同時使用所有這些描述符? PCA應該能夠清除那些沒有貢獻的人。你能用python代碼做一個例子嗎? – tarrasch 2013-05-09 12:21:02

+0

你的方法存在的問題是,你試圖用純粹的「程序員方法」來解決它,而不是依靠可以給你捷徑的計算機視覺文獻。 我相信你可以混合一些描述符並且配置一個巨大的特徵矢量並且規範化每個矢量,但是你的方法看起來很「粗暴」。你甚至沒有定義你打算使用我之前提到的類別的圖像類型。 – Arturo 2013-05-09 15:48:16

+0

這是故意的。我試圖通過不訴諸於計算機視覺的東西。我想讓算法自己弄清楚圖像中的重要部分。這應完全取決於數據。 – tarrasch 2013-05-10 07:12:25

0

首先,導入庫並提取圖片

from sklearn import datasets  
%matplotlib inline 
import sklearn as sk 
import numpy as np 
import matplotlib.pyplot as plt 
digits = datasets.load_digits() 
X_digits = digits.data 
y_digits = digits.target 
ind4 = np.where(y_digits==4) 
ind5= np.where(y_digits==5) 
plt.imshow(X_digits[1778].reshape((8,8)),cmap=plt.cm.gray_r) 
0

然後使用此功能:

XX = np.arange(64)

DEF feature_11(XX) :

yy=xx.reshape(8,8) 
feature_1 = sum(yy[0:2,:]) 
feature11 = sum(feature_1) 
print (feature11) 
return feature11 

feature_11(X_digits [1778])

然後用LDA:

從sklearn.discriminant_analysis進口LinearDiscriminantAnalysis

CLF = LinearDiscriminantAnalysis()

ind_all = np.arange(0,LEN(y_digits ))

np.random.shuffle(ind_all)

ind_training = ind_all [0:INT(0.8 * LEN(ind_all))]

ind_test = ind_all [INT(0.8 * LEN(ind_all)):]

clf.fit(X_digits [ind_training],y_digits [ind_training])

y_predicted = clf.predict(X_digits [ind_test ])

plt.subplot(211)

plt.stem(y_predicted)

plt.subplot(212)

plt.stem(y_digits [ind_test], 'R')

plt.stem(y_digits [ind_test] - y_predicted, 'R')

總和(y_predicted == y_digits [ind_test])/ LEN (y_predicted)

+0

請給你的答案補充一些補充。只顯示代碼可能會造成混淆。 – 2016-12-21 10:52:08