openCV c ++: problemas al trabajar con CvBoost (Adaboost classifer)

Estoy creando una aplicación para clasificar a los humanos en imágenes de entornos urbanos.

Entreno a un clasificador de la siguiente manera:

int main (int argc, char **argv)
{

/* STEP 2. Opening the file */
//1. Declare a structure to keep the data
  CvMLData cvml;
//2. Read the file
  cvml.read_csv ("directory/train_rand.csv");
//3. Indicate which column is the response
  cvml.set_response_idx (0);

/* STEP 3. Splitting the samples */
//1. Select 4000 for the training
  CvTrainTestSplit cvtts (4000, true);
//2. Assign the division to the data
  cvml.set_train_test_split (&cvtts);

  printf ("Training ... ");
/* STEP 4. The training */
//1. Declare the classifier
  CvBoost boost;
//2. Train it with 100 features
  boost.train (&cvml, CvBoostParams (CvBoost::REAL,100, 0, 1, false, 0),
           false);

/* STEP 5. Calculating the testing and training error */
// 1. Declare a couple of vectors to save the predictions of each sample
  std::vector<float> train_responses, test_responses;
// 2. Calculate the training error
  float fl1 = boost.calc_error (&cvml, CV_TRAIN_ERROR, &train_responses);
// 3. Calculate the test error
  float fl2 = boost.calc_error (&cvml, CV_TEST_ERROR, &test_responses);

  cout<<"Error train: "<<fl1<<endl;

  cout<<"Error test: "<<fl2<<endl;

/* STEP 6. Save your classifier */
// Save the trained classifier
  boost.save ("./trained_boost_4000samples-100ftrs.xml", "boost");

  return 0;
}

train_rand.csv es un archivo donde la primera columna es la categoría. El resto de las columnas serán las características del problema. Por ejemplo, podría haber usado tres características. Cada uno de ellos representa el promedio de rojo, azul y verde por píxel en la imagen. Así que mi archivo csv debería verse así. Tenga en cuenta que en la primera columna estoy usando un carácter, por lo que OpenCV reconoce eso como una categoría.

B,124.34,45.4,12.4
B,64.14,45.23,3.23
B,42.32,125.41,23.8
R,224.4,35.34,163.87
R,14.55,12.423,89.67
...

Para mi problema real, estoy usando 100 características y 8000 muestras. Entreno al clasificador con la mitad de los datos y los pruebo con el resto.

Después del entrenamiento, obtengo un error de prueba de alrededor del 5% (lo cual es bastante bueno para solo 100 funciones).

Ahora quiero usar el clasificador en nuevos datos:

CvBoost boost

boost.load("directory/trained_boost_4000samples-100ftrs.xml");

float x = boost.predict(SampleData,Mat(),Range::all(),false,false);
cout<<x;

Estoy ejecutando este código en miles de muestras y siempre genera el mismo valor, que es 2. Realmente no entiendo lo que estoy haciendo mal aquí, pero incluso si entrenara para clasificar de forma incorrecta, no clasificaría el 100% de las veces de la misma manera, el error de prueba que calculé antes muestra que El clasificador debería funcionar bien.

Una cosa que me molesta es que SampleData tiene que tener el mismo número de columnas que la muestra que solía entrenar. La cuestión es que los datos utilizados para entrenar tienen 100 columnas + 1 respuesta, y si intento ejecutar el clasificador con solo 100 características, se produce una excepción que dice que los tamaños no coinciden. Si ejecuto el clasificador con 101 características (lo cual es absolutamente arbitrario), funciona, pero los resultados no tienen ningún sentido.

Puede alguien ayudarme con esto? ¡Gracias por adelantado!

Saludos

Respuestas a la pregunta(1)

Su respuesta a la pregunta