summaryrefslogtreecommitdiff
path: root/2005/i/robert/src/ovision/see/segmLearn.cc
diff options
context:
space:
mode:
Diffstat (limited to '2005/i/robert/src/ovision/see/segmLearn.cc')
-rw-r--r--2005/i/robert/src/ovision/see/segmLearn.cc176
1 files changed, 176 insertions, 0 deletions
diff --git a/2005/i/robert/src/ovision/see/segmLearn.cc b/2005/i/robert/src/ovision/see/segmLearn.cc
new file mode 100644
index 0000000..e13abd2
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/segmLearn.cc
@@ -0,0 +1,176 @@
+// segmLearn.cc - Classe Segmentation
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file segmLearn.cc Apprentissage du réseau de neurones
+
+#include "segmLearn.hh"
+#include <iostream>
+
+/// Constructor SegmLearn
+SegmLearn::SegmLearn () :
+ freq_ (0)
+{
+}
+
+/// Destructor SegmLearn
+SegmLearn::~SegmLearn ()
+{
+ delete [] freq_;
+}
+
+/// Genere des poids pour un noeud
+/// @param numNode numéro du noeud à changer
+void
+SegmLearn::weightsGen (const int numNode)
+{
+ const int minWeight = 30;
+ const int maxWeight = 220;
+ // Parcours des 3 composantes
+ for(int i=0; i<3; i++)
+ {
+ // Attribution aléatoire des poids
+ node_[numNode*3+i] = (unsigned char) (255.0*rand()/(RAND_MAX+1.0));
+ if (node_[numNode*3+i] < minWeight)
+ node_[numNode*3+i] = minWeight;
+ else if (node_[numNode*3+i] > maxWeight)
+ node_[numNode*3+i] = maxWeight;
+ }
+}
+
+
+/// 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
+SegmLearn::buildNN (const int nbOutput_, const bool loadFromFile)
+{
+ this->nbOutput_ = nbOutput_;
+ // Initialisation des noeuds du NN
+ delete [] node_;
+ node_ = new unsigned char[nbOutput_*3];
+ delete [] index_;
+ index_ = new int[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_->nnNbNodeMax < nbOutput_)
+ {
+ std::cerr << "SegmLearn::buildNN : Nombre de nodes insuffisants dans le fichier poids" << std::endl;
+ return;
+ }
+ // Charge les poids du NN et l'index des couleurs
+ for (int i = 0; i<nbOutput_*3; i++)
+ node_[i] = oconfig_->node[i];
+ for (int i = 0; i<nbOutput_; i++)
+ index_[i] = oconfig_->index[i];
+ }
+ else
+ {
+ //initialition des noeuds aléatoirement
+ srand((unsigned)time(0));
+ for(int i=0; i<nbOutput_; i++)
+ {
+ // Remise à zéro de l'index
+ index_[i] = i;
+ // Regeneration de nouveaux poids
+ weightsGen (i);
+ }
+ }
+}
+
+
+/// Entraine un reseau de neurones
+void
+SegmLearn::trainNN (Img *img)
+{
+ unsigned long pixelNum;
+ unsigned char *tabData_;
+ int numOutputMax;
+ tabData_ = img->tabData_;
+ delete [] freq_;
+ freq_ = new int[nbOutput_];
+ for(int i=0; i<nbOutput_; i++)
+ freq_[i] = 0;
+ for(unsigned long i=0; i<oconfig_->nnNil; i++)
+ {
+ // On choisit un pixel au hasard
+ pixelNum = (unsigned long)(img->nbPixels_*(rand()/(RAND_MAX+1.0)));
+ numOutputMax = findColorNN (tabData_ + pixelNum*3);
+ // Mis a jour des poids
+ for(int k=0; k<3; k++)
+ {
+ node_[numOutputMax*3+k] =
+ (unsigned char)((node_[numOutputMax*3+k] + oconfig_->nnSl*tabData_[pixelNum*3+k])/(1+oconfig_->nnSl));
+ // Recompense pour la sortie qui travaille
+ freq_[numOutputMax]++;
+ }
+ // Verification des noeuds inutiles à partir de 300 iterations
+ if ((i%300) == 299)
+ {
+ for (int k=0; k < nbOutput_; k++)
+ {
+ // Regeneration de nouveaux poids
+ if (freq_[k] < oconfig_->nnLazyThreshold)
+ weightsGen (k);
+ // On remet le compteur a zero
+ freq_[k] = 0;
+ }
+ }
+ }
+}
+
+
+/// 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
+SegmLearn::findColorNN (const unsigned char *x, const bool testOutputMax) const
+{
+ int numOutputMax=0;
+ int output[nbOutput_];
+ int tmp;
+ // Calcul des valeurs de sorties du NN pour ce pixel
+ for(int j=0; j<nbOutput_; j++)
+ {
+ output[j] = 0;
+ // Parcours des 3 composantes
+ for(int k=0; k<3; k++)
+ {
+ // XXX Ne pas oublier de mettre abs si on ne calcule pas les carrés
+ tmp = node_[j*3+k]-x[k];
+ // Si on est en yuv ou hsi et que c'est la composante de lum_inosite, on ajoute un poids pour affecter son influence
+ if (k == lumPos_)
+ //|| ((img->colorMode == Image) && k==2))
+ output[j] += (int) oconfig_->nnInfluLum * 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_->nnThresholdOutput))
+ numOutputMax = Segm::undefined;
+ return numOutputMax;
+}
+
+
+
+
+/// 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
+SegmLearn::giveColor (const unsigned char *x, const bool testOutputMax, const bool nodeProcess)
+{
+ if (lumPos_ >= 0) addLum (x[lumPos_]);
+ if (nodeProcess)
+ return index_ [findColorNN (x, testOutputMax)];
+ else
+ return findColorNN (x, testOutputMax);
+}
+