13

So I have a matrix with my sample images (all turned into vectors) which was run trough PCA/LDA, and a vector which denotes the class each images belongs to. Now I want to use the OpenCV SVM class to train my SVM (I am using Python, OpenCV 2.3.1). But I have a problem with defining the parameters:

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

I am stuck on how to define the type of SVM (linear, etc.) and other stuff. In C++ you define it by stating for example: svm_type=CvSVM::C_SVC...Python doesn't have that. C++ also has a special class to store these parameters -> CvSVMParams. Can someone give me an example of this in Python? Like defining the SVM type, gamma, etc.

The 2.3.1 docs says it like this:

Python: cv2.SVM.train(trainData, responses[, varIdx[, sampleIdx[, params]]]) → retval

What are varIdx and sampleIdx, and how to define the params?

3
  • 1
    I am currently reading docs, but meanwhile, you can use alternative solution: convert your matrix to numpy and use sk-learn for machine learning task. Commented Jan 1, 2012 at 0:23
  • Hi! Try those examples: code.ros.org/svn/opencv/trunk/opencv/samples/python2/… Commented Jan 1, 2012 at 0:59
  • timgluz THX that's exactly what I was looking for...could you please copy the SVM part from the link in an answer so I can accept it (so that other people can find the answer right away and u get credit)...the SVM part is from line 79 to 91... Commented Jan 1, 2012 at 10:41

2 Answers 2

20

To use OpenCV machine learning algorithms, you have to write some wrapper classes:

1. First parent class

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. Finally SvM wrapper:

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.Example usage:

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)

Setting parameters

Setting parameters is simple - just write a dictionary that holds the parameters as keys. You should look original documentation to see all possible parameters and allowed values: http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#cvsvmparams

Yes, possible values for svm_type and kernel_type are in C++, but there is easy way to convert those constants into Python representation, for example CvSVM::C_SVC is written as cv2.SVM_C_SVC in Python.

Prelude To get more wrappers for machine learning algorithms, look into letter-recog.py example in your opencv examples on disk or open url of OpenCV repository: https://github.com/Itseez/opencv/tree/master/samples/python2

Sign up to request clarification or add additional context in comments.

3 Comments

This looks very promising. I have registered at ros.org but when I enter my name and password for the link to python samples, I get this dialog box and cannot get past it. "To view this page, you must log in to this area on code.ros.org:443:" Is there a special name/password for this svn area, beyond my own?
Hi! Sadly they cancelled public view for this repository. I'll post some workaround very soon.
This code works only for OpenCV 2. In OpenCV 3, the SVM functions have been moved from cv2 to cv2.ml, and to create the model, the new function is cv2.ml.SVM_create()
1

Adapted from timgluz version, but uses "train_auto" instead of "train". cv2 will find parameters "C", "gamma", ... for us.

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.