Python OpenCV SVM实现

13 投票
2 回答
20170 浏览
提问于 2025-04-17 09:18

我有一个矩阵,里面存放着我的样本图像(这些图像都被转化成了向量),然后我用主成分分析(PCA)和线性判别分析(LDA)处理过这些数据。现在我想用OpenCV的支持向量机(SVM)类来训练我的模型(我使用的是Python和OpenCV 2.3.1)。不过我在定义参数的时候遇到了问题:

test = cv2.SVM()
test.train(trainData, responses, ????)

我不知道怎么定义SVM的类型(比如线性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是什么?我该怎么定义这些参数呢?

2 个回答

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)
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仓库的链接:https://github.com/Itseez/opencv/tree/master/samples/python2

撰写回答