我正在使用Python OpenCV包装器,我想使用SVM实现一个简单的分类器。
首先,我创建一个填充零的矩阵,其形状为:
np.zeros( (len(positives)+len(negatives), samples_height*samples_width), dtype = np.float32)
之后,我将所有正面和负面样本作为一行加载到矩阵中:
for i, file in enumerate(os.listdir("svm_data/positives")):
image = cv2.imread("svm_data/positives/"+file, 0)
traindata[i,:] = np.ravel(image)
labels.append(0)
for i, file in enumerate(os.listdir("svm_data/negatives")):
image = cv2.imread("svm_data/negatives/"+file, 0)
traindata[positives+i,:] = np.ravel(image)
labels.append(1)
最后我设置了SVM:
self.svm = cv2.ml.SVM_create()
self.svm.setType(cv2.ml.SVM_C_SVC)
self.svm.setGamma(0.5)
self.svm.setC(30)
self.svm.setKernel(cv2.ml.SVM_LINEAR)
self.svm.train(traindata, cv2.ml.ROW_SAMPLE, np.array(labels, dtype = np.int32))
self.svm.save('svm.dat')
顺便说一下。看来svm.load还没有实现。
但是现在,如果我想通过调用以下方法测试我的训练有关SVM的图像来自我的肯定文件夹(或任何其他图像):
image = np.float32(cv2.imread("svm_data/positives/158_233_486.png", 0))
print self.svm.predict(np.ravel(image))
程序将终止并抛出
OpenCV错误:断言中的断言失败(samples.cols == var_count&& samples.type()== CV_32F)
我读了几篇回答“错误意味着,输入图像的大小或类型与样本不同”但输出结果为:
print traindata[i,:].shape
print traindata[i,:].dtype
print np.ravel(image).shape
print np.ravel(image).dtype
是
(1681,)
float32
(1681,)
float32
现在我很困惑,希望有人能帮助我。
由于
---------------- UPDATE ----------------
我的样本矩阵的形状似乎存在问题 我在svm.cpp
中的1930行上面添加了一些打印件printf("samples.cols: %d\n", samples.cols);
printf("var_count: %d\n", var_count);
printf("samples.type(): %d\n", samples.type());
printf("CV_32F: %d\n", CV_32F);
CV_Assert( samples.cols == var_count && samples.type() == CV_32F );
OpenCV重建后,我的输出是:
samples.cols: 1
var_count: 1681
samples.type(): 5
CV_32F: 5
OpenCV Error: Assertion failed (samples.cols == var_count && samples.type() == CV_32F) in predict, file opencv/modules/ml/src/svm.cpp, line 1938
---------------- UPDATE ----------------
好的我已经知道了!
image = np.float32(cv2.imread("svm_data/positives/158_233_486.png", 0))
print self.svm.predict(np.ravel(image))
加载的图像是1xn矩阵,但svm预测在我的情况下是nx1数组,所以这对我来说是修复的:)
print self.svm.predict(np.ravel(image)[None, :])