Commit e766e506 authored by Aylen Ricca's avatar Aylen Ricca
Browse files

distributing integrating classes

parent 4ea32bcf
......@@ -26,10 +26,13 @@
#define CYAN_REGION 6
#define MAGENTA_REGION 7
#define CANT_REGIONS 15
//#define CANT_REGIONS 15
#define CANT_REGIONS 40 //FIXME
#define IMAGE_WIDTH 160 //px
#define IMAGE_HEIGHT 120 //px
//#define IMAGE_WIDTH 160 //px
//#define IMAGE_HEIGHT 120 //px
#define IMAGE_WIDTH 640 //px
#define IMAGE_HEIGHT 480 //px
#define DISTANCIA_FOCAL_HAVIMO 164//d(cm) * ancho(px) / ancho(cm)
#define DFH_FOR_PROPORTION 179
......
......@@ -18,10 +18,22 @@ using namespace cv;
#include <cvblob.h>
using namespace cvb;
#define WIDTH 640
#define HEIGHT 480
#define WIDTH 320
#define HEIGHT 240
#define FPS 5
#define CANT_CALIBRACIONES 1
#define CANT_CALIBRACIONES 7
static const char filename[] = "futbotVision.conf";
static const char imagen [] = "imgs/imagen00000.jpg";
//static const char imagen [] = "imgs/imagen10000.jpg"; // determinar cual es la pelota
//static const char imagen [] = "imgs/imagen10001.jpg"; // determinar cual es la pelota
//static const char imagen [] = "imgs/imagen10010.jpg"; // determinar cual es la pelota y por que ve 2 aliados
//static const char imagen [] = "imgs/imagen10011.jpg"; // determinar cual es la pelota y por que ve 2 aliados
//static const char imagen [] = "imgs/imagen10100.jpg"; // ver xq ve opp y my goal y un solo landmark
//static const char imagen [] = "imgs/imagen10101.jpg"; // ver xq ve my goal y opp lat post y un solo landmark
//static const char imagen [] = "imgs/imagen10110.jpg"; // ver xq ve my goal con alto likeness
//static const char imagen [] = "imgs/imagen10111.jpg"; // ver xq ve my goal con alto likeness
//static const char imagen [] = "imgs/imagen11000.jpg"; // ver el tema de robot proximo
CvCapture *capture;
IplImage *img;
......@@ -29,19 +41,73 @@ CvSize imgSize;
IplImage *frame;
int frameNumber;
// AMARILLO - AZUL - NARANJA - MAGENTA -cam web --FIXME levantar del .conf
//cv::Scalar calibsMIN [] = {cv::Scalar(19,208,80),cv::Scalar(43,26,40),cv::Scalar(6,160,75),cv::Scalar(167,110,44)};
//cv::Scalar calibsMAX [] = {cv::Scalar(24,249,125),cv::Scalar(113,132,58),cv::Scalar(15,226,184),cv::Scalar(179,187,102)};
/* BALL - FIELD - MY GOAL - OPP GOAL - ROBOT BODY - CYAN - MAGENTA */
cv::Scalar *calibsMIN;
cv::Scalar *calibsMAX;
// AMARILLO - AZUL - NARANJA - MAGENTA -cam CSI
cv::Scalar calibsMIN [] = {cv::Scalar(9,156,44),cv::Scalar(121,83,46),cv::Scalar(13,229,75),cv::Scalar(-4,172,42)};
cv::Scalar calibsMAX [] = {cv::Scalar(17,245,124),cv::Scalar(121,83,46),cv::Scalar(13,229,75),cv::Scalar(-4,172,42)};
/**
* Carga el archivo de configuracion.
*/
int getConfiguration(){
FILE *file = fopen(filename, "r");
int a, b, c;
int cont = 0, pos = 0;
char line [128];
cv::Scalar s;
calibsMIN = (cv::Scalar*) malloc(sizeof(cv::Scalar)*CANT_CALIBRACIONES);
calibsMAX = (cv::Scalar*) malloc(sizeof(cv::Scalar)*CANT_CALIBRACIONES);
if (file != NULL)
{
while (fgets(line, sizeof line, file) != NULL) /* read a line */
{
if ((line[0] != '\n') && (line[0] != '#') && (line[0] != '{') && (line[0] != '}'))
{
sscanf(line, " %[^\n]", line); /* skip white spaces at the beginning*/
switch (cont%4)
{
case 2: /* min HSI */
sscanf(line, "hsiMin={%d,%d,%d}\n", &a, &b, &c);
calibsMIN[pos] = cv::Scalar(a, b, c);
break;
case 3: /* max HSI */
sscanf(line, "hsiMax={%d,%d,%d}\n", &a, &b, &c);
calibsMAX[pos] = cv::Scalar(a, b, c);
pos++;
break;
default: /* discard */
break;
}
cont++;
}
}
fclose (file);
}
else
{
perror(filename); /* error openning the file*/
return -1;
}
// printf("----------------------\n");
// for (int i=0; i<CANT_CALIBRACIONES; i++) {
// printf("HSI min : {%f,%f,%f}\n",calibsMIN[i].val[0],calibsMIN[i].val[1],calibsMIN[i].val[2]);
// }
// printf("----------------------\n");
// for (int i=0; i<CANT_CALIBRACIONES; i++) {
// printf("HSI max : {%f,%f,%f}\n",calibsMAX[i].val[0],calibsMAX[i].val[1],calibsMAX[i].val[2]);
// }
return 0;
}
/**
* Inicializa las estructuras que utiliza. Carga archivo de configuracion
* Inicializa las estructuras que utiliza.
*/
int utilBlobs_initialize(){
if (!(capture = cvCaptureFromCAM(0))){
getConfiguration();
/*if (!(capture = cvCaptureFromCAM(0))){
fprintf(stderr, "== ERROR 0 - revisar conexion a camara.\n");
return 0;
}
......@@ -55,8 +121,8 @@ int utilBlobs_initialize(){
return 0;
}
img = cvRetrieveFrame(capture);
//img = cvLoadImage("segmentada.png",1);
*/
img = cvLoadImage(imagen,1);
imgSize = cvGetSize(img);
frame = cvCreateImage(imgSize, img->depth, img->nChannels);
frameNumber = 0;
......@@ -69,19 +135,20 @@ int utilBlobs_initialize(){
*/
void utilBlobs_terminate(){
cvReleaseImage(&frame);
cvReleaseCapture(&capture);
// cvReleaseCapture(&capture);
}
/**
* Obtiene un nuevo frame de la camara conectada, retorna -1 si hay algún problema con la lectura desde la camara
*/
int utilBlobs_getFrame(){
if (!cvGrabFrame(capture)) {
/* if (!cvGrabFrame(capture)) {
fprintf(stderr,"== ERROR 1 - revisar conexion a camara. Posible desconexion.\n");
return 0;
}
img = cvRetrieveFrame(capture);
//img = cvLoadImage("segmentada.png",1);
*/
img = cvLoadImage(imagen,1);
cvConvertScale(img, frame, 1, 0);
return 1;
}
......@@ -94,7 +161,7 @@ void getOneColorBlobs (const IplImage *hsvImage, IplImage * labelImg, CvBlobs &b
cvInRangeS(hsvImage, min, max, segmentated);
if (min.val[0] < 0) {
min.val[0] = 180 - min.val[0];
min.val[0] = 180 + min.val[0];
max.val[0] = 180;
IplImage *segmentated2 = cvCreateImage(imgSize, 8, 1);
cvInRangeS(hsvImage, min, max, segmentated2);
......@@ -132,27 +199,15 @@ struct blob fillZeros(){
res.min_x = (unsigned int) 0;
res.max_y = (unsigned int) 0;
res.min_y = (unsigned int) 0;
/*
printf("===== START DEBUG =====\n");
printf("reg_idx: %u\n", res.region_index);
printf("reg_col: %u\n", res.region_color);
printf("nro_pix: %u\n", res.number_of_pixels);
printf("suma__x: %u%u\n", res.sum_of_x_coord_high, res.sum_of_x_coord_low);
printf("suma__y: %u%u\n", res.sum_of_y_coord_high, res.sum_of_y_coord_low);
printf("maxim_x: %u\n", res.max_x);
printf("minim_x: %u\n", res.min_x);
printf("maxim_y: %u\n", res.max_y);
printf("minim_y: %u\n", res.min_y);
printf("===== FIN DEBUG =====\n");
*/
return res;
}
struct blob infoToBlob(CvBlob info, unsigned int region_idx){
struct blob infoToBlob(CvBlob info, unsigned int region_idx, unsigned int region_color){
struct blob res;
res.region_index = region_idx+1;
res.region_color = BALL_REGION;
res.region_index = region_idx;
res.region_color = region_color;
res.number_of_pixels = info.area;
res.sum_of_x_coord_high = 0;
......@@ -165,19 +220,19 @@ struct blob infoToBlob(CvBlob info, unsigned int region_idx){
res.min_x = info.minx;
res.max_y = info.maxy;
res.min_y = info.miny;
/*
printf("===== START DEBUG =====\n");
printf("reg_idx: %u\n", res.region_index);
printf("reg_col: %u\n", res.region_color);
printf("nro_pix: %u\n", res.number_of_pixels);
printf("suma__x: %u%u\n", res.sum_of_x_coord_high, res.sum_of_x_coord_low);
printf("suma__y: %u%u\n", res.sum_of_y_coord_high, res.sum_of_y_coord_low);
printf("maxim_x: %u\n", res.max_x);
printf("minim_x: %u\n", res.min_x);
printf("maxim_y: %u\n", res.max_y);
printf("minim_y: %u\n", res.min_y);
printf("===== FIN DEBUG =====\n");
*/
// printf("===== START DEBUG =====\n");
// printf("reg_idx: %u\n", res.region_index);
// printf("reg_col: %u\n", res.region_color);
// printf("nro_pix: %u\n", res.number_of_pixels);
// printf("suma__x: %u%u\n", res.sum_of_x_coord_high, res.sum_of_x_coord_low);
// printf("suma__y: %u%u\n", res.sum_of_y_coord_high, res.sum_of_y_coord_low);
// printf("maxim_x: %u\n", res.max_x);
// printf("minim_x: %u\n", res.min_x);
// printf("maxim_y: %u\n", res.max_y);
// printf("minim_y: %u\n", res.min_y);
// printf("===== FIN DEBUG =====\n");
return res;
}
......@@ -214,29 +269,27 @@ void utilBlobs_getBlobs(struct blob* result){
IplImage *hsv = cvCreateImage(imgSize, 8, 3);
cvCvtColor(frame,hsv,CV_BGR2HSV);
int indice=0;
CvBlobs blobsitos;
for (int i=0; i < CANT_CALIBRACIONES; i++){
IplImage *labelImg = cvCreateImage(cvGetSize(frame), IPL_DEPTH_LABEL, 1);
getOneColorBlobs(hsv, labelImg, blobsitos, imgSize, calibsMIN[0], calibsMAX[0]);
cvRenderBlobs(labelImg, blobsitos, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX);
CvBlobs::const_iterator it = blobsitos.begin();
unsigned int indice;
for(indice = 0; indice < CANT_REGIONS; indice++) {
for (int i=0; i < CANT_CALIBRACIONES && indice < CANT_REGIONS; i++){
IplImage *labelImg = cvCreateImage(cvGetSize(frame), IPL_DEPTH_LABEL, 1);
getOneColorBlobs(hsv, labelImg, blobsitos, imgSize, calibsMIN[i], calibsMAX[i]);
cvRenderBlobs(labelImg, blobsitos, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX);
std::stringstream filename;
filename << "debugBLOB_" << std::setw(5) << std::setfill('0') << indice << ".png";
cvSaveImage(filename.str().c_str(),frame);
CvBlobs::const_iterator it = blobsitos.begin();
CvBlob* bloby;
if (it!=blobsitos.end()){
while (it!=blobsitos.end() && indice < CANT_REGIONS){
bloby = (*it).second;
result [indice] = infoToBlob(*bloby, indice);
result [indice++] = infoToBlob(*bloby, indice+1, i+1);
it++;
} else {
result [indice] = fillZeros();
}
}
//saveBlobs(frameNumber++, blobsitos);
cvReleaseImage(&labelImg);
cvReleaseBlobs(blobsitos);
cvReleaseImage(&labelImg);
cvReleaseBlobs(blobsitos);
}
cvReleaseImage(&hsv);
while(indice < CANT_REGIONS) result [indice++] = fillZeros();
}
......@@ -561,11 +561,14 @@ unsigned short int vision_objRec_detectRivals(void) {
*/
double getBlobRoundness(struct blob b) {
unsigned short int aux_width = b.max_x - b.min_x;
unsigned short int aux_height = b.max_y - b.min_y;
if(aux_width > aux_height) {
return aux_height / aux_width;
} else {
return aux_width / aux_height;
unsigned short int aux_height = b.max_y - b.min_y;
printf ("......... ROUNDNESS :: %d - %d\n", aux_width, aux_height);
if(aux_width > aux_height) {
printf ("......... ROUNDNESS = %f\n", ((double)aux_height/(double)aux_width));
return (double)aux_height / (double)aux_width;
} else {
printf ("......... ROUNDNESS = %f\n", ((double)aux_width/(double)aux_height));
return (double)aux_width/(double)aux_height;
}
}
......@@ -592,19 +595,24 @@ unsigned short int vision_objRec_detectBall(void) {
//Obtenemos la mejor pelota
for(i = 0; i < CANT_REGIONS; i++) {
if(blobs[i].region_index != INVALID_REGION && blobs[i].region_color == BALL_REGION) {
if(blobs[i].region_index != INVALID_REGION && blobs[i].region_color == BALL_REGION) {
printf("...posible pelota...\n");
if(blobs[i].max_y >= BOTTOM_MARGEN_PROXIMITY) {
aux_ball_roundness = 1;
aux_ball_roundness = 1;
printf("......roundness(=1) = %f...\n",aux_ball_roundness);
} else {
aux_ball_roundness = getBlobRoundness(blobs[i]);
if(aux_ball_roundness < MIN_BALL_ROUNDNESS)
continue;
printf("......roundness = %f...\n",aux_ball_roundness);
if(aux_ball_roundness < MIN_BALL_ROUNDNESS){
printf("......roundness menor a MIN (=%f)...\n",aux_ball_roundness);
continue;
}
}
//Encontre una pelota
if(blob_ball == NULL) {
if(blob_ball == NULL) {
printf("..... first ball\n");
//Es la primera region que parece una bola
blob_ball = &blobs[i];
......@@ -618,7 +626,8 @@ unsigned short int vision_objRec_detectBall(void) {
}
} else {
printf(".....another ball\n");
//Ya hay un objeto identificado como la bola. Me quedo con el mas grande y cuadrado.
int blob_w = blobs[i].max_x - blobs[i].min_x;
int blob_h = blobs[i].max_y - blobs[i].min_y;
......
......@@ -57,17 +57,20 @@ void processBlobs(void) {
//Identificamos la bola
unsigned short int hayPelota = vision_objRec_detectBall();
printf("PELOTA = %d\n");
printf("PELOTA = %hu\n",hayPelota);
//Identificamos los agentes
vision_objRec_detectAllies();
vision_objRec_detectRivals();
unsigned short int cant_allies = vision_objRec_detectAllies();
printf("ALLIES = %hu\n",cant_allies);
unsigned short int cant_rivals = vision_objRec_detectRivals();
printf("RIVALS = %hu\n",cant_rivals);
//Identificamos los landmarks
struct vision_obj* right_landmark = vision_objRec_getDetectedRightLandmark();
struct vision_obj* left_landmark = vision_objRec_getDetectedLeftLandmark();
if(right_landmark != NULL) {
printf("RIGHT LANDMARK\n");
//Los landmarks son de interes para la estrategia. Copio los datos del landmark a objects.
objects[obj_size].type = RIGHT_LANDMARK;
objects[obj_size].x = right_landmark->x;
......@@ -78,6 +81,7 @@ void processBlobs(void) {
}
if(left_landmark != NULL) {
printf("LEFT LANDMARK\n");
//Los landmarks son de interes para la estrategia. Copio los datos del landmark a objects.
objects[obj_size].type = LEFT_LANDMARK;
objects[obj_size].x = left_landmark->x;
......@@ -90,6 +94,7 @@ void processBlobs(void) {
struct vision_obj* my_goal = vision_objRec_getDetectedMyGoal();
if(my_goal != NULL) {
printf("MY GOAL\n");
//El arco es de interez para la estrategia. Copio los datos del arco a objects.
objects[obj_size].type = MY_GOAL;
objects[obj_size].x = my_goal->x;
......@@ -102,6 +107,7 @@ void processBlobs(void) {
struct vision_obj* opp_goal = vision_objRec_getDetectedOppGoal();
if(opp_goal != NULL) {
printf("OPP GOAL\n");
//El arco es de interez para la estrategia. Copio los datos del arco a objects.
objects[obj_size].type = OPP_GOAL;
objects[obj_size].x = opp_goal->x;
......
all: utilsBlobs.cpp icvBlobs.c clasification.c objRecognition.c vision.c main.c
g++ -g `pkg-config opencv cvblob --cflags --libs` utilsBlobs.cpp icvBlobs.c clasification.c objRecognition.c vision.c main.c -o TEST_BASIC_0
/*############################################################
# #
# Proyecto Visión robótica y reconstrucción espacial #
# con aplicaciones prácticas. 2010 #
# http://www.fing.edu.uy/inco/grupos/mina/pGrado/vision2010 #
# #
############################################################*/
#include "clasification.h"
#include "iVisionModule.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
//#include <util/delay.h>
int HaViMo_id;
/**
* Verifica si 2 blobs pueden ser combinados. Retorna la posicion del blob a, de acuerdo al blob b
* a blob para comparar con b
* b blob para comparar con a
* x_threshold umbral para la comparacion en el eje x
* y_threshold umbral para la comparacion en el eje y
* Retorna:
* 0 No pueden ser combinados
* 1 A arriba de B
* 2 A debajo B
* 3 A a la izquierda de B
* 4 A a la derecha de B
*/
int vision_cla_canBlobsBeMerged(struct blob a, struct blob b, unsigned int x_threshold, unsigned int y_threshold) {
if((abs(a.min_x - b.min_x) < x_threshold) && (abs(a.max_x - b.max_x) < x_threshold)) {
//A TOP B
if(abs(a.max_y - b.min_y) < y_threshold)
return 1;
//A BOT B
if(abs(a.min_y - b.max_y) < y_threshold)
return 2;
}
if((abs(a.min_y - b.min_y) < y_threshold) && (abs(a.max_y - b.max_y) < y_threshold)) {
//A LEFT B
if(abs(a.max_x - b.min_x) < x_threshold)
return 3;
//A RIGHT B
if(abs(a.min_x - b.max_x) < x_threshold)
return 4;
}
return 0;
}
/**
* Inicializa las estructuras que utiliza la clasificacion, inicializando iHaViMo.
* HaViMo_dxl_ID identificador dynamixel de havimo
* baudnum baudnum con que se incializara la libreria dynamixel
*/
int vision_cls_initialize(int HaViMo_dxl_ID, int baudnum) {
HaViMo_id = HaViMo_dxl_ID;
return iVisionModule_initialize(HaViMo_dxl_ID, baudnum);
}
/**
* Mergear los blobs, a partir de un region_color especifico, usando como umbral GOAL_THRESHOLD_X y GOAL_THRESHOLD_Y
* blobs blobs a mergear
* region_color color que se debe mergear
* dont_process_blob array que define si no se debe procesar un blob
*/
void vision_cls_mergeGoalBlobsByRegion(struct blob* blobs, short int region_color, unsigned short int* dont_process_blob) {
//Preprocesamiento del array de blobs
unsigned short int i;
unsigned short int j;
unsigned short int blobs_merged;
do {
blobs_merged = 0;
for(i = 0; i < CANT_REGIONS; i++) {
if(blobs[i].region_index != INVALID_REGION && blobs[i].region_color == region_color && !dont_process_blob[i]) {
for(j = i + 1; j < CANT_REGIONS; j++) {
if(!dont_process_blob[j] && blobs[j].region_index != INVALID_REGION && blobs[i].region_color == blobs[j].region_color &&
vision_cla_canBlobsBeMerged(blobs[i], blobs[j], GOAL_THRESHOLD_X, GOAL_THRESHOLD_Y)) {
//Se combinan los blobs
blobs[j].region_index = 0;
if(blobs[i].max_x < blobs[j].max_x)
blobs[i].max_x = blobs[j].max_x;
if(blobs[i].min_x > blobs[j].min_x)
blobs[i].min_x = blobs[j].min_x;
if(blobs[i].max_y < blobs[j].max_y)
blobs[i].max_y = blobs[j].max_y;
if(blobs[i].min_y > blobs[j].min_y)
blobs[i].min_y = blobs[j].min_y;
blobs_merged = 1;
}
}
}
}
} while(blobs_merged);
}
/**
* Retorna el preprocesamiento realizado sobre el resultado de la segmentacion de la imagen de HaViMo.
* Si no hay un nuevo frame para procesar se retorna NULL.
* force_frame fuerza la obtencion del frame.
*/
struct blob* vision_cls_getNextFrame(unsigned short int force_frame) {
struct blob* blobs = iVisionModule_getNextFrame(HaViMo_id);
if(force_frame) {
while(blobs == NULL){
//_delay_ms(FORCE_FRAME_MS_DELAY);
blobs = iVisionModule_getNextFrame(HaViMo_id);
}
} else {
if(blobs == NULL) { printf("null blobs\n"); return NULL; }
}
//Preprocesamiento del array de blobs
unsigned short int i;
unsigned short int j;
unsigned short int blobs_merged;
do {
blobs_merged = 0;
for(i = 0; i < CANT_REGIONS; i++) {
printf("procesar\n");
if(blobs[i].region_index != INVALID_REGION) {
printf("no es invalida\n");
if(blobs[i].max_x - blobs[i].min_x <= MIN_PX_SIZE_FOR_BLOB || blobs[i].max_y - blobs[i].min_y <= MIN_PX_SIZE_FOR_BLOB) {
//Invalidamos el blob
printf("invalido blobs\n");
blobs[i].region_index = INVALID_REGION;
} else {
for(j = i + 1; j < CANT_REGIONS; j++) {
if(blobs[j].region_index != INVALID_REGION && blobs[i].region_color == blobs[j].region_color &&
vision_cla_canBlobsBeMerged(blobs[i], blobs[j], THRESHOLD_X, THRESHOLD_Y)) {
//Se combinan los blobs
printf("blobs combinados\n");
blobs[j].region_index = INVALID_REGION;
if(blobs[i].max_x < blobs[j].max_x)
blobs[i].max_x = blobs[j].max_x;
if(blobs[i].min_x > blobs[j].min_x)
blobs[i].min_x = blobs[j].min_x;
if(blobs[i].max_y < blobs[j].max_y)
blobs[i].max_y = blobs[j].max_y;
if(blobs[i].min_y > blobs[j].min_y)
blobs[i].min_y = blobs[j].min_y;
blobs[i].number_of_pixels += blobs[j].number_of_pixels;
blobs_merged = 1;
}
}
}
} else printf("es invalida\n");
}
} while(blobs_merged);
return blobs;
}
/**
* Finaliza clasificacion. Finaliza iHaViMo.
*/
void vision_cls_terminate(void) {
iVisionModule_terminate();
}
/*############################################################
# #
# Proyecto Visión robótica y reconstrucción espacial #
# con aplicaciones prácticas. 2010 #
# http://www.fing.edu.uy/inco/grupos/mina/pGrado/vision2010 #
# #
############################################################*/
/**
* clasification.h: Modulo de clasificacion de la capa de Vision.
* Encargado del preprocesamiento de los blobs obtenidos de HaViMo.
* @author: Gonzalo Gismero
*/
#ifndef I_VISION_CLASIFICATION
#define I_VISION_CLASIFICATION
#include "iVisionModule.h"
#define MIN_PX_SIZE_FOR_BLOB 2//Quitamos los blobs que tengan un ancho o largo de 2 pixeles
#define FORCE_FRAME_MS_DELAY 10 //miliseconds
#define THRESHOLD_Y 7//10 //px
#define THRESHOLD_X 7//10 //px
//Luego del identificar los blobs de los landmarks, se intenta juntar los blobs que sobraron para los arcos con un umbral mayor
#define GOAL_THRESHOLD_X 15//px
#define GOAL_THRESHOLD_Y 15//px
/**
* Inicializa las estructuras que utiliza la clasificacion, inicializando iHaViMo.
* HaViMo_dxl_ID identificador dynamixel de havimo
* baudnum baudnum con que se incializara la libreria dynamixel
*/
int vision_cls_initialize(int HaViMo_dxl_ID, int baudnum);
/**
* Finaliza clasificacion. Finaliza iHaViMo.
*/
void vision_cls_terminate(void);
/**
* Retorna el preprocesamiento realizado sobre el resultado de la segmentacion de la imagen de HaViMo.