Python OpenCV支持向量机实现

13

我有一个矩阵,其中包含我的样本图像(全部转换为向量),经过PCA / LDA处理,并且有一个向量指示每个图像所属的类别。现在我想使用OpenCV SVM类来训练我的SVM(我正在使用Python,OpenCV 2.3.1)。但是我在定义参数方面遇到了问题:

test = cv2.SVM()
test.train(trainData, responses, ????)
我卡在如何定义 SVM(线性等)类型和其他内容上。在 C++ 中,您可以通过声明 svm_type = CvSVM :: C_SVC 等来定义它。但是 Python 没有这个功能。C++ 还有一个特殊的类来存储这些参数-> CvSVMParams。有人能给我一个 Python 的例子吗?例如定义 SVM 类型,gamma 等。
2.3.1 文档以以下方式说明:
Python: cv2.SVM.train(trainData, responses[, varIdx[, sampleIdx[, params]]]) → retval

varIdx和sampleIdx是什么,如何定义这些参数?


1
我目前正在阅读文档,但同时你可以使用替代方案:将矩阵转换为numpy并使用sk-learn进行机器学习任务。 - timgluz
你好!请尝试这些例子:https://code.ros.org/svn/opencv/trunk/opencv/samples/python2/letter_recog.py - timgluz
timgluz 谢谢,这正是我在寻找的...你能否将链接中的 SVM 部分复制到答案中,以便我可以接受它(这样其他人就可以立即找到答案并给你信用)...SVM 部分是从第 79 行到第 91 行。 - Veles
2个回答

20

要使用OpenCV机器学习算法,您需要编写一些包装类:

1. 第一个父类

class StatModel(object):
    '''parent class - starting point to add abstraction'''    
    def load(self, fn):
        self.model.load(fn)
    def save(self, fn):
        self.model.save(fn)

2. 最后是SvM包装器:

class SVM(StatModel):
    '''wrapper for OpenCV SimpleVectorMachine algorithm'''
    def __init__(self):
        self.model = cv2.SVM()

    def train(self, samples, responses):
        #setting algorithm parameters
        params = dict( kernel_type = cv2.SVM_LINEAR, 
                       svm_type = cv2.SVM_C_SVC,
                       C = 1 )
        self.model.train(samples, responses, params = params)

    def predict(self, samples):
        return np.float32( [self.model.predict(s) for s in samples])

3. 示例用法:

import numpy as np
import cv2

samples = np.array(np.random.random((4,2)), dtype = np.float32)
y_train = np.array([1.,0.,0.,1.], dtype = np.float32)

clf = SVM()
clf.train(samples, y_train)
y_val = clf.predict(samples)

设置参数

设置参数很简单 - 只需编写一个包含参数作为键的字典。您应该查看原始文档以查看所有可能的参数和允许的值:http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#cvsvmparams

是的,svm_type和kernel_type的可能值在C++中,但有一种简单的方法将这些常量转换为Python表示方式,例如,CvSVM::C_SVC在Python中写作cv2.SVM_C_SVC。

前言 要获得更多机器学习算法的包装器,请查看您的opencv示例程序中的letter-recog.py示例,或者打开OpenCV存储库的URL:https://github.com/Itseez/opencv/tree/master/samples/python2


这看起来非常有前途。我已经在ros.org注册了,但是当我输入我的用户名和密码以获取Python示例的链接时,我会得到这个对话框,无法继续。 "要查看此页面,您必须登录到code.ros.org:443上的此区域:"除了我的用户名和密码之外,这个svn区域还有特殊的名称/密码吗? - zerowords
嗨!很遗憾,他们取消了此存储库的公共查看。我很快会发布一些解决方法。 - timgluz
这段代码仅适用于OpenCV 2。在OpenCV 3中,SVM函数已从cv2移动到cv2.ml,并且要创建模型,需要使用新的函数cv2.ml.SVM_create()。 - jpyams

1
改编自timgluz版本,但使用“train_auto”而不是“train”。 cv2会为我们找到参数“C”,“gamma”等。
import cv2
import numpy as np

class Learn:
    def __init__(self, X, y):
        self.est = cv2.SVM()
        params = dict(kernel_type=cv2.SVM_LINEAR, svm_type=cv2.SVM_C_SVC)
        self.est.train_auto(X, y, None, None, params, 3) #kfold=3 (default: 10)

    def guess(self, X):
        return np.float32( [self.est.predict(s) for s in X])

X = np.array(np.random.random((6,2)), dtype = np.float32)
y = np.array([1.,0.,0.,1.,0.,1.], dtype = np.float32)
g = Learn(X,y).guess(X)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接