2011-12-31 20 views
10

Tengo una matriz con mis imágenes de muestra (todas convertidas en vectores) que se ejecutó a través de PCA/LDA, y un vector que indica la clase a la que pertenecen cada imagen. Ahora quiero usar la clase OpenCV SVM para entrenar mi SVM (estoy usando Python, OpenCV 2.3.1). Pero tengo un problema con la definición de los parámetros:Implementación Python OpenCV SVM

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

estoy atascado en cómo definir el tipo de SVM (lineal, etc.) y otras cosas. En C++ lo defines diciendo, por ejemplo: svm_type = CvSVM :: C_SVC ... Python no tiene eso. C++ también tiene una clase especial para almacenar estos parámetros -> CvSVMParams. ¿Alguien puede darme un ejemplo de esto en Python? Al igual que la definición del tipo SVM, gamma, etc.

la documentación 2.3.1 dice así:

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

¿Cuáles son varIdx y sampleIdx, y cómo definir los parametros?

+1

Actualmente estoy leyendo documentos, pero mientras tanto, puede usar una solución alternativa: convierta su matriz en numpy y use sk-learn para la tarea de aprendizaje automático. – timgluz

+0

¡Hola! Pruebe esos ejemplos: https://code.ros.org/svn/opencv/trunk/opencv/samples/python2/letter_recog.py – timgluz

+0

timgluz THX eso es exactamente lo que estaba buscando ... podría copiar la parte SVM de el enlace en una respuesta para que pueda aceptarlo (para que otras personas puedan encontrar la respuesta de inmediato y obtener crédito) ... la parte de SVM es de la línea 79 a 91 ... – Veles

Respuesta

18

Para utilizar OpenCV algoritmos de aprendizaje automático, usted tiene que escribir algunas clases contenedoras:

1. Primera clase padre

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. Finalmente SvM envoltorio:

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.El uso de la muestra:

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) 

parámetros de ajuste

Configuración de parámetros es simple - acaba de escribir un diccionario que contiene los parámetros como claves. Debe buscar la documentación original para ver todos los posibles parámetros y valores permitidos: http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#cvsvmparams

Sí, valores posibles para svm_type y kernel_type están en C++, pero no hay manera fácil de convertir esas constantes en representación de Python, por ejemplo CvSVM :: C_SVC está escrito como cv2.SVM_C_SVC en Python.

Preludio Para obtener más contenedores para algoritmos de aprendizaje automático, mira en letter-recog.py ejemplo, en sus ejemplos OpenCV en el disco o URL abierta de OpenCV repositorio: https://github.com/Itseez/opencv/tree/master/samples/python2

+0

Esto parece muy prometedor. Me he registrado en ros.org pero cuando ingreso mi nombre y contraseña para el enlace a las muestras de Python, obtengo este cuadro de diálogo y no puedo pasarlo. "Para ver esta página, debe iniciar sesión en esta área en code.ros.org:443:" ¿Existe un nombre/contraseña especial para este área de svn, más allá del mío? – zerowords

+0

¡Hola! Lamentablemente cancelaron la vista pública de este repositorio. Publicaré alguna solución muy pronto. – timgluz

+0

Este código funciona solo para OpenCV 2. En OpenCV 3, las funciones de SVM se han movido de cv2 a cv2.ml, y para crear el modelo, la nueva función es cv2.ml.SVM_create() – jpyams

1

Adaptado de timgluz versión, pero usa "train_auto" en lugar de "train". cv2 encontrará los parámetros "C", "gamma", ... para nosotros.

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)