【问题标题】:SVM image prediction PythonSVM 图像预测 Python
【发布时间】:2019-07-21 12:30:11
【问题描述】:

我从我的火车数据集中的图像中提取了一些特征,然后我应用了这些特征并将数据拆分为火车并使用train_test_split 进行测试:

Train data  : (60, 772)
Test data   : (20, 772)
Train labels: (60,)
Test labels : (20,)

接下来我要做的是将 SVM 分类器应用于测试数据集中的图像并查看结果。

# create the model - SVM
#clf = svm.SVC(kernel='linear', C=40)
clf = svm.SVC(kernel='rbf', C=10000.0, gamma=0.0001)

# fit the training data to the model
clf.fit(trainDataGlobal, trainLabelsGlobal)

# path to test data
test_path = "dataset/test"

# loop through the test images
for index,file in enumerate(glob.glob(test_path + "/*.jpg")):
    # read the image
    image = cv2.imread(file)

    # resize the image
    image = cv2.resize(image, fixed_size)

    # predict label of test image
    prediction = clf.predict(testDataGlobal)
    prediction = prediction[index]
    #print("Accuracy: {}%".format(clf.score(testDataGlobal, testLabelsGlobal) * 100 ))

    # show predicted label on image
    cv2.putText(image, train_labels[prediction], (20,30), cv2.FONT_HERSHEY_TRIPLEX, .7 , (0,255,255), 2)

    # display the output image
    plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    plt.show()

我没有得到很好的准确度,尽管我可以看到它说准确率为 60%。然而,大多数图像都被错误地标记了。我在prediction 中传递了错误的参数吗?

我可以做些什么来改善这一点?

编辑:我用下面的代码尝试了你所说的,但我收到一个错误,说我应该重塑我的feature_vector。所以我这样做了,然后我得到以下错误。

(作为参考:feature_extraction_method(image).shape(772,)。)

for filename in test_images:

    # read the image and resize it to a fixed-size
    img = cv2.imread(filename)
    img = cv2.resize(img, fixed_size)

    feature_vector = feature_extraction_method(img)
    prediction = clf.predict(feature_vector.reshape(-1, 1))
    cv2.putText(img, prediction, (20, 30), cv2.FONT_HERSHEY_TRIPLEX, .7 , (0, 255, 255), 2)
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.show()   

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-71-2b8ff4146d8e> in <module>()
     19 
     20     feature_vector = feature_extraction_method(img)
---> 21     prediction = clf.predict(feature_vector.reshape(-1, 1))
     22     cv2.putText(img, prediction, (20, 30), cv2.FONT_HERSHEY_TRIPLEX, .7 , (0, 255, 255), 2)
     23     plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py in predict(self, X)
    546             Class labels for samples in X.
    547         """
--> 548         y = super(BaseSVC, self).predict(X)
    549         return self.classes_.take(np.asarray(y, dtype=np.intp))
    550 

/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py in predict(self, X)
    306         y_pred : array, shape (n_samples,)
    307         """
--> 308         X = self._validate_for_predict(X)
    309         predict = self._sparse_predict if self._sparse else self._dense_predict
    310         return predict(X)

/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py in _validate_for_predict(self, X)
    457             raise ValueError("X.shape[1] = %d should be equal to %d, "
    458                              "the number of features at training time" %
--> 459                              (n_features, self.shape_fit_[1]))
    460         return X
    461 

ValueError: X.shape[1] = 1 should be equal to 772, the number of features at training time 

【问题讨论】:

    标签: python image-processing scikit-learn svm


    【解决方案1】:

    您的代码有两个主要问题。

    首先,您不需要在 for 循环的每次交互中对整个测试集进行分类。一次预测一张图像的类别标签就足够了:

        prediction = svm.clf.predict([testDataGlobal[index, :]])
    

    注意testDataGlobal[index, :] 必须括在方括号[ ] 中,因为predict() 方法需要一个类似二维数组的变量。

    其次,也是最重要的,假设函数glob 产生一个包含三个图像文件的列表,即imgA.jpgimgB.jpgimgC.jpg,让我们将它们对应的特征向量表示为featsAfeatsBfeatsC。为使您的代码正常工作,testDataGlobal 的排列方式如下:

    [featsA, 
     featsB, 
     featsC]
    

    如果特征向量的排列顺序不同,您可能会得到错误的结果。

    您可以通过以下sn-p正确标记图像(未测试):

    test_images = glob.glob("dataset/test/*.jpg")
    
    for filename in test_images:
        img = cv2.imread(filename)
        img = cv2.resize(img, fixed_size)
        feature_vector = your_feature_extraction_method(img)
        prediction = svm.clf.predict([feature_vector])
        cv2.putText(img, prediction[0], (20, 30), 
                    cv2.FONT_HERSHEY_TRIPLEX, .7 , (0, 255, 255), 2)
        plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        plt.show()    
    

    其中your_feature_extraction_method() 代表一个函数,它使用图像并返回其特征向量(类似一维数组)。

    注意:不要忘记将feature_vector 括在方括号[ ] 中。您还可以使用以下任何一种方法将feature_vector 的维度增加一个维度:

        prediction = svm.clf.predict(feature_vector[None, :])
        prediction = svm.clf.predict(feature_vector[np.newaxis, :])
        prediction = svm.clf.predict(np.atleast_2d(feature_vector))
    

    【讨论】:

    • 谢谢!!我尝试了您所说的,但出现错误(请参阅上面的编辑)。你知道我该如何解决这个问题吗?
    • 我错过了在调用predict() 方法时将feature_vector 括在方括号中。感谢您发现这一点。我刚刚编辑了我的答案,现在代码应该可以正常工作了。
    • ---------------------------------------------------------------------------TypeError Traceback (most recent call last)&lt;ipython-input-96-8e8dcbb06af1&gt; in &lt;module&gt;()---&gt; 23 cv2.putText(img, prediction, (20, 30), cv2.FONT_HERSHEY_TRIPLEX, .7 , (0, 255, 255), 2)TypeError: bad argument type for built-in operation
    • 它在 cv2.putText 中给了我一个错误 - 它不接受 prediction 作为参数
    • prediction 是一个元素的数组。您应该将prediction[0] 传递给cv2.putText() 以修复该错误。分类器为所有图像分配相同类别标签 (1) 的最可能原因是 trainDataGlobaltrainLabelsGlobal(或两者)中包含的数据存在缺陷。您还应该为Cgamma 尝试不同的值。
    猜你喜欢
    • 2014-07-09
    • 2018-05-29
    • 2019-11-19
    • 2018-08-12
    • 2020-07-05
    • 2013-05-22
    • 2018-11-01
    • 2017-07-10
    • 2019-07-06
    相关资源
    最近更新 更多