// segmNN.cc - Classe Segmentation // nono - Programme du robot Efrei Robotique I1-I2 2004 // Copyright (C) 2004 Olivier Gaillard /// @file segmNN.cc Segmente l'image et cree un tableau contenant des valeurs segmentees, creation du reseau de neurones #include "segmNN.h" #include #include #include using namespace std; /// Constructor SegmNN /// @param img classe img permettant d'acceder au donnees de l'image a traiter /// @param oconfig classe oconfig permettant d'acceder aux variables de oconfiguration SegmNN::SegmNN (Img *img) { this->img = img; oconfig = OConfig::GetInstance (); nbOutput = oconfig->nn_NbCouleurs; node = NULL; index = NULL; tabSegm = NULL; } /// Destructor SegmNN SegmNN::~SegmNN () { delete [] node; delete [] index; delete [] tabSegm; } /// Affiche les poids du reseau de neurones (neural network : NN) void SegmNN::ShowNodes () { // Affichage des poids du NN cout << "Poids:"; for(int i=0; icolorMode == YUV) && k==0) || ((img->colorMode == HSI) && k==2)) output[j] += (int) oconfig->nn_influ_lum * tmp * tmp; // Sinon calcul normal else output[j] += tmp * tmp; } // On cherche la sortie ayant le plus haut niveau if (output[j] < output[numOutputMax]) numOutputMax = j; } return numOutputMax; } /// Construit un reseau de neurones /// @param nbOutput nombre de noeuds de la couche de sortie du NN /// @param loadFromFile (GENERATE ou LOADFROMFILE) indique si les poids sont charges d'un fichier ou generes aleatoirement void SegmNN::BuildNN (int nbOutput, int loadFromFile) { this->nbOutput = nbOutput; // Permet de charger les poids du NN depuis un fichier ou en les initialisant aleatoirement if (loadFromFile) { // Verifie si le nombre de poids donne dans le fichier est suffisant if (oconfig->nbNodeMax < nbOutput) { cerr << "SegmNN::BuildNN : Nombre de nodes insuffisants dans le fichier poids\n"; } else { // Charge les poids du NN delete [] node; node = new unsigned char[nbOutput*3]; for (int i = 0; inode[i]; // Initialisation de l'index de couleur delete [] index; index = new int[nbOutput]; for (int i = 0; iindex[i]; } } // Si on ne souhaite pas loader les poids a partir d'un fichier else { cerr << "SegmNN::BuildNN : Utilisé la classe SegmLearn pour l'apprentissage du NN\n"; } } /// Renvoie le code de la couleur segmentee /// @param *x pointeur vers un tableau contenant une valeur RGB /// @param testOutputMax choix de l'utilisation d'un sueil maxi pour la sortie pour éviter qu'une couleur trop différente soit attribuer à une autre couleur unsigned char SegmNN::FindColorNN (unsigned char *x, bool testOutputMax) { int numOutputMax=0; int output[nbOutput]; int tmp; // Calcul des valeurs de sorties du NN pour ce pixel for(int j=0; jcolorMode == YUV) && k==0) || ((img->colorMode == HSI) && k==2)) output[j] += (int) oconfig->nn_influ_lum * tmp * tmp; // Sinon calcul normal else output[j] += tmp * tmp; } // On selectionne la sortie ayant la plus grande valeur comme couleur if (output[numOutputMax] > output[j]) numOutputMax = j; } // Test si la valeur de sortie est assez proche d'une couleur du rezo if ((testOutputMax) && (output[numOutputMax] > oconfig->nn_threshold_output)) numOutputMax = UNDEFINED; return numOutputMax; } /// Segmente l'image avec le reseau de neurones void SegmNN::Segm () { unsigned char* tabData = img->tabData; if (tabSegm) delete [] tabSegm; tabSegm = new unsigned char[img->nbPixels]; // Parcours de l'image pour la segmentation // On recupere l'index et non le numero de sortie du NN for (unsigned long i=0; inbPixels; i++) { tabSegm[i] = index[FindColorNN (tabData+i*3)]; } } /// Segmente l'image pour une seule couleur uniquement et permet donc d'isoler une couleur /// @param numColor numero de la couleur a isoler void SegmNN::Segm (int numColor) { unsigned char* tabData = img->tabData; if (tabSegm) delete [] tabSegm; tabSegm = new unsigned char[img->nbPixels]; // Parcours de l'image pour la segmentation for (unsigned long i=0; inbPixels; i++) { if (FindColorNN (tabData+i*3) == numColor) tabSegm[i] = 1; else tabSegm[i] = 0; } }