SVM

clasificador por SVM

NOTA: el entrenamiento está probado solo para opencv cvs después de agosto. Este es un ejemplo de SVM para clasificar personas de vehículos Bases de datos: Vectores de soporte:

code format="c" /*ejemplo hecho por francisco carlos calderón con licencia CC 3.0 [] */

#include 
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 

using std::ofstream; using std::cout; using std::cin; using std::endl; using std::ios; using std::cerr; using std::endl; using std::setprecision;
 * 1) include
 * 2) include
 * 3) include

int main (int argc, char **argv) {   /*Crear variables a ser usadas para toma de muestras*/ char filename[300]; //totales de muestras a usar en este caso personas y vehiculos const int total_de_personas=878; const int cantidad_personas=778;

const int total_de_vehiculos=615; const int cantidad_vehiculos=515;

const int totales=cantidad_vehiculos+cantidad_personas; const int h_bins = 12, s_bins = 10; //filas hue columnas saturación /*momentos*/ CvMoments momentos; CvHuMoments momentos_hu; const int momentos_de_hu=7;

const int tam = (h_bins * s_bins)+momentos_de_hu+momentos_de_hu; //const int tam = 29; float datos_totales[totales*tam]; int etiquetas[totales]; int indice=0; int indice_etiqueta=0; cvNamedWindow( "imagen", CV_WINDOW_AUTOSIZE );

/*recopiladores de muestras de vehiculos y personas*/ printf("alistando datos para entrenar..... \n"); for(int n=1;n<=cantidad_vehiculos;n++) {       sprintf(filename, "C:\\bases de datos final final\\vehiculos\\vehiculo (%d).jpg", n);//básicamente imprime pero en una cadena de caracteres IplImage* src = NULL; src=cvLoadImage(filename, CV_LOAD_IMAGE_ANYCOLOR);//carga las imagenes if(!src) //si no se pudo cargar sale {           printf("no se pudo cargar la imagen\n"); return -1; }       //convertir imagen cargada a hsv y separar los planos IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 ); cvCvtColor( src, hsv, CV_BGR2HSV ); IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* planes[] = { h_plane, s_plane }; cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );

//crear histograma CvHistogram* hist; int   hist_size[] = { h_bins, s_bins }; float h_ranges[]  = { 0, 180 };          // hue es [0,180] float s_ranges[]  = { 0, 255 }; float* ranges[]   = { h_ranges, s_ranges }; hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );

//crea un histograma en 2D de los planos de hue y saturación, cvCalcHist( planes, hist, 0, 0 ); cvNormalizeHist(hist,1.0);

for( int h = 0; h < h_bins; h++ ) {           for( int s = 0; s < s_bins; s++ ) {               datos_totales[indice] = (float)cvQueryHistValue_2D( hist, h, s ); //printf("datos %f \n",datos_totales[indice]); indice++; }       }

/*momentos*/ cvMoments( s_plane, &momentos, 0 ); cvGetHuMoments( &momentos, &momentos_hu ); datos_totales[indice] = (float) momentos_hu.hu1; indice++; datos_totales[indice] = (float) momentos_hu.hu2; indice++; datos_totales[indice] = (float) momentos_hu.hu3; indice++; datos_totales[indice] = (float) momentos_hu.hu4; indice++; datos_totales[indice] = (float) momentos_hu.hu5; indice++; datos_totales[indice] = (float) momentos_hu.hu6; indice++; datos_totales[indice] = (float) momentos_hu.hu7; indice++; cvMoments( h_plane, &momentos, 0 ); cvGetHuMoments( &momentos, &momentos_hu ); datos_totales[indice] = (float) momentos_hu.hu1; indice++; datos_totales[indice] = (float) momentos_hu.hu2; indice++; datos_totales[indice] = (float) momentos_hu.hu3; indice++; datos_totales[indice] = (float) momentos_hu.hu4; indice++; datos_totales[indice] = (float) momentos_hu.hu5; indice++; datos_totales[indice] = (float) momentos_hu.hu6; indice++; datos_totales[indice] = (float) momentos_hu.hu7; indice++; etiquetas[indice_etiqueta]=0; indice_etiqueta++; //cvShowImage("imagen",src); //cvWaitKey(2); cvReleaseImage(&src); cvReleaseImage(&hsv); cvReleaseImage(&v_plane); cvReleaseImage(&planes[0]); cvReleaseImage(&planes[1]); }//fin del for donde quedan las muestras de vehiculos

for(int n=1;n<=cantidad_personas;n++) {       sprintf(filename, "C:\\bases de datos final final\\personas\\persona (%d).jpg", n);//básicamente imprime pero en una cadena de caracteres IplImage*src=NULL; src=cvLoadImage(filename, CV_LOAD_IMAGE_ANYCOLOR);//carga las imagenes if(!src) //si no se pudo cargar sale {           printf("no se pudo cargar la imagen"); return -1; }       //convertir imagen cargada a hsv y separar los planos IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 ); cvCvtColor( src, hsv, CV_BGR2HSV ); IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* planes[] = { h_plane, s_plane }; cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );

//crear histograma CvHistogram* hist; int   hist_size[] = { h_bins, s_bins }; float h_ranges[]  = { 0, 180 };          // hue is [0,180] float s_ranges[]  = { 0, 255 }; float* ranges[]   = { h_ranges, s_ranges }; hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );

//crea un histograma en 2D de los planos de hue y saturación, cvCalcHist( planes, hist, 0, 0 ); cvNormalizeHist(hist,1.0); for( int h = 0; h < h_bins; h++ ) {           for( int s = 0; s < s_bins; s++ ) {               datos_totales[indice] = (float)cvQueryHistValue_2D( hist, h, s ); //printf("datos %f \n",datos_totales[indice]); indice++; }       }        cvMoments( s_plane, &momentos, 0 ); cvGetHuMoments( &momentos, &momentos_hu ); datos_totales[indice] = (float) momentos_hu.hu1; indice++; datos_totales[indice] = (float) momentos_hu.hu2; indice++; datos_totales[indice] = (float) momentos_hu.hu3; indice++; datos_totales[indice] = (float) momentos_hu.hu4; indice++; datos_totales[indice] = (float) momentos_hu.hu5; indice++; datos_totales[indice] = (float) momentos_hu.hu6; indice++; datos_totales[indice] = (float) momentos_hu.hu7; indice++; cvMoments( h_plane, &momentos, 0 ); cvGetHuMoments( &momentos, &momentos_hu ); datos_totales[indice] = (float) momentos_hu.hu1; indice++; datos_totales[indice] = (float) momentos_hu.hu2; indice++; datos_totales[indice] = (float) momentos_hu.hu3; indice++; datos_totales[indice] = (float) momentos_hu.hu4; indice++; datos_totales[indice] = (float) momentos_hu.hu5; indice++; datos_totales[indice] = (float) momentos_hu.hu6; indice++; datos_totales[indice] = (float) momentos_hu.hu7; indice++; etiquetas[indice_etiqueta]=1; indice_etiqueta++; //cvShowImage("imagen",src); //cvWaitKey(2); cvReleaseImage(&src); cvReleaseImage(&hsv); cvReleaseImage(&v_plane); cvReleaseImage(&planes[0]); cvReleaseImage(&planes[1]); }//fin del for donde quedan las muestras de personas

/*-ENTRENAMIENTO-*/

int sv_num; CvSVM svm = CvSVM ; CvSVMParams param; CvTermCriteria criteria; CvMat data_mat, res_mat; /* Creaciòn de los vectores de datos y etiquetas:     */ /*acà me toca leer las muestras a ser clasificadas*/ //los datos van asì: //todos los datos forman un vector, donde los primeros n datos son las caracteristicas de la   //primera muestra, los segundos n de la segunda y asì sucesivamente

/*parametros de aprendizaje y conversiòn de las muestras a estandar de ml*/ //   //el vector res me dice a que clase corresponde cada dato // (aprendizaje de los datos por SVM   /* CvSVM::POLY - polynomial kernel: d(x,y) = (gamma*(x•y)+coef0)degree */    //param = CvSVMParams (CvSVM::C_SVC, CvSVM::POLY, 4.0, 2.0, 0.0, 10.0, 0.5, 0.1, NULL, criteria);    /* CvSVM::RBF - radial-basis-function kernel; a good choice in most cases: d(x,y) = exp(-gamma*|x-y|2) */

cvInitMatHeader (&data_mat, totales, tam, CV_32FC1, datos_totales);//el 3 parametro es el nùmero de caracteristicas cvInitMatHeader (&res_mat, totales, 1, CV_32SC1, etiquetas); criteria = cvTermCriteria (CV_TERMCRIT_EPS, 2000, FLT_EPSILON);

//param = CvSVMParams (CvSVM::C_SVC,   //    CvSVM::RBF,    //    10.0,//_degree    //    5.767,//_gamma    //    1.0,//_coef0    //    10,//_C    //    0.5,//_nu    //    0.1,//_p    //    NULL,    //    criteria); /* CvSVMParams( int _svm_type, int _kernel_type, double _degree, double _gamma, double _coef0, double _C, double _nu, double _p, CvMat* _class_weights, CvTermCriteria _term_crit );

param = CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 10, 1.0, 1000, 0.5, 0.1, NULL, criteria); printf("entrenando..... \n"); svm.train (&data_mat, &res_mat, NULL, NULL, param); //descomente esto y comente el svm.train para usar el train auto, solo funciona con el 1.1 y posterior no 1.0 //CvParamGrid elce; //      elce.min_val = 2; //      elce.max_val = 1000; //      elce.step = 1.3; //8 iteraciones con 0.25- 100 - 2 //CvParamGrid elgama; //      elgama.min_val = 0.1; //      elgama.max_val = 100; //      elgama.step = 1.5;//5 iteraciones con 0.1 - 8 - 2.2 //CvParamGrid elresto; //      elresto.step = 1; // //   svm.train_auto (&data_mat, &res_mat, NULL, NULL, param,10, //       elce, //       elgama, //       elresto, //       elresto, //       elresto, //       elresto);

printf("salvando datos..... \n"); svm.save("C:\\svm_entrenado_automatico.xml"); //printf("mejores parametros encontrados:\n C= %f \n nu= %f \n p= %f \n gamma= %f \n degree= %f \n coef0= %f \n",   param.C,param.nu,param.p,param.gamma,param.degree,param.coef0); printf("probando..... \n"); // (vectores de soporte   sv_num = svm.get_support_vector_count;    printf("encontre %d vectores de soporte \n",sv_num);    cvWaitKey (0);

/*probar que tan bueno es :):):)::)                                                                predicción*/

float dato_a_probar[tam]; int indice_peque=0; int bien=0; int mal=0; float resp;

for(int n=1;n<=total_de_vehiculos;n++) {       sprintf(filename, "C:\\bases de datos final final\\vehiculos\\vehiculo (%d).jpg", n);//básicamente imprime pero en una cadena de caracteres IplImage*src=NULL; src=cvLoadImage(filename, CV_LOAD_IMAGE_ANYCOLOR);//carga las imagenes if(!src) //si no se pudo cargar sale {           printf("no se pudo cargar la imagen"); return -1; }       //convertir imagen cargada a hsv y separar los planos IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 ); cvCvtColor( src, hsv, CV_BGR2HSV ); IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* planes[] = { h_plane, s_plane }; cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );

//crear histograma CvHistogram* hist; int   hist_size[] = { h_bins, s_bins }; float h_ranges[]  = { 0, 180 };          // hue is [0,180] float s_ranges[]  = { 0, 255 }; float* ranges[]   = { h_ranges, s_ranges }; hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 ); CvMat m;       //crea un histograma en 2D de los planos de hue y saturación, cvCalcHist( planes, hist, 0, 0 ); cvNormalizeHist(hist,1.0); indice_peque=0; for( int h = 0; h < h_bins; h++ ) {           for( int s = 0; s < s_bins; s++ ) {               dato_a_probar[indice_peque] = (float)cvQueryHistValue_2D( hist, h, s ); //printf("datos %f \n",datos_totales[indice]); indice_peque++; }       }

/*momentos*/ cvMoments( s_plane, &momentos, 0 ); cvGetHuMoments( &momentos, &momentos_hu ); dato_a_probar[indice_peque] = (float) momentos_hu.hu1; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu2; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu3; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu4; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu5; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu6; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu7; indice_peque++; cvMoments( h_plane, &momentos, 0 ); cvGetHuMoments( &momentos, &momentos_hu ); dato_a_probar[indice_peque] = (float) momentos_hu.hu1; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu2; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu3; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu4; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu5; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu6; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu7; indice_peque++; /*fin momentos*/ cvInitMatHeader (&m, 1, tam, CV_32FC1, dato_a_probar); resp = svm.predict (&m); if((int) resp ==0) bien++; else {       printf(filename); printf("\n"); mal++; //cvShowImage("imagen",src); //cvWaitKey(1000); }       //cvWaitKey(10); cvReleaseImage(&src); cvReleaseImage(&hsv); cvReleaseImage(&v_plane); cvReleaseImage(&planes[0]); cvReleaseImage(&planes[1]); }   printf("encontre %d vehiculos bien y %d vehiculos mal\n",bien,mal); indice_peque=0; bien=0; mal=0;

for(int n=1;n<=total_de_personas;n++) {       sprintf(filename, "C:\\bases de datos final final\\personas\\persona (%d).jpg", n);//básicamente imprime pero en una cadena de caracteres IplImage*src=NULL; src=cvLoadImage(filename, CV_LOAD_IMAGE_ANYCOLOR);//carga las imagenes if(!src) //si no se pudo cargar sale {           printf("no se pudo cargar la imagen"); return -1; }       //convertir imagen cargada a hsv y separar los planos IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 ); cvCvtColor( src, hsv, CV_BGR2HSV ); IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* planes[] = { h_plane, s_plane }; cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );

//crear histograma CvHistogram* hist; int   hist_size[] = { h_bins, s_bins }; float h_ranges[]  = { 0, 180 };          // hue is [0,180] float s_ranges[]  = { 0, 255 }; float* ranges[]   = { h_ranges, s_ranges }; hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );

//crea un histograma en 2D de los planos de hue y saturación, cvCalcHist( planes, hist, 0, 0 ); cvNormalizeHist(hist,1.0); indice_peque=0; CvMat m2; for( int h = 0; h < h_bins; h++ ) {           for( int s = 0; s < s_bins; s++ ) {               dato_a_probar[indice_peque] = (float)cvQueryHistValue_2D( hist, h, s ); //printf("datos %f \n",datos_totales[indice]); indice_peque++; }       }        /*momentos*/ cvMoments( s_plane, &momentos, 0 ); cvGetHuMoments( &momentos, &momentos_hu ); dato_a_probar[indice_peque] = (float) momentos_hu.hu1; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu2; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu3; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu4; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu5; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu6; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu7; indice_peque++; cvMoments( h_plane, &momentos, 0 ); cvGetHuMoments( &momentos, &momentos_hu ); dato_a_probar[indice_peque] = (float) momentos_hu.hu1; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu2; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu3; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu4; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu5; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu6; indice_peque++; dato_a_probar[indice_peque] = (float) momentos_hu.hu7; indice_peque++; /*fin momentos*/ cvInitMatHeader (&m2, 1, tam, CV_32FC1, dato_a_probar); resp = svm.predict (&m2); if((int) resp ==1) bien++; else {       printf(filename); printf("\n"); mal++; //cvShowImage("imagen",src); //cvWaitKey(1000); }       //cvWaitKey(10); cvReleaseImage(&src); cvReleaseImage(&hsv); cvReleaseImage(&v_plane); cvReleaseImage(&planes[0]); cvReleaseImage(&planes[1]); }   printf("encontre %d personas bien y %d personas mal\n",bien,mal); cvWaitKey(0); return 0; }

code