summaryrefslogtreecommitdiff
path: root/2004/i/nono/src/ovision/segmLearn.cc
diff options
context:
space:
mode:
Diffstat (limited to '2004/i/nono/src/ovision/segmLearn.cc')
-rw-r--r--2004/i/nono/src/ovision/segmLearn.cc195
1 files changed, 195 insertions, 0 deletions
diff --git a/2004/i/nono/src/ovision/segmLearn.cc b/2004/i/nono/src/ovision/segmLearn.cc
new file mode 100644
index 0000000..4a2217e
--- /dev/null
+++ b/2004/i/nono/src/ovision/segmLearn.cc
@@ -0,0 +1,195 @@
+// segmLearn.cc - Classe Segmentation
+// nono - Programme du robot Efrei Robotique I1-I2 2004
+// Copyright (C) 2004 Olivier Gaillard
+
+/// @file segmLearn.cc Apprentissage du réseau de neurones
+
+#include "segmLearn.h"
+#include <iostream>
+
+/// Constructor SegmLearn
+
+/// @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
+SegmLearn::SegmLearn (Img *img) : SegmNN (img)
+{
+ freq = NULL;
+}
+
+/// Destructor SegmLearn
+SegmLearn::~SegmLearn ()
+{
+ delete [] freq;
+}
+
+
+/// Genere des poids pour un noeud
+/// @param numNode numéro du noeud à changer
+void
+SegmLearn::WeightsGen (int numNode)
+{
+ // 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] < 30) node[numNode*3+i] = 30;
+ else if (node[numNode*3+i] > 220) node[numNode*3+i] = 220;
+ }
+}
+
+
+/// 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(int nbOutput, int loadFromFile)
+{
+ SegmNN::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)
+ {
+ std::cerr << "SegmNN::BuildNN : Nombre de nodes insuffisants dans le fichier poids" << std::endl;
+ }
+ else
+ {
+ // Charge les poids du NN et l'index des couleurs
+ delete [] node;
+ node = new unsigned char[nbOutput*3];
+ for (int i = 0; i<nbOutput*3; i++)
+ node[i] = oconfig->node[i];
+ delete [] index;
+ index = new int[nbOutput];
+ for (int i = 0; i<nbOutput; i++)
+ index[i] = oconfig->index[i];
+ freq = new int[nbOutput];
+ }
+ return;
+ }
+
+ //initialition de random
+ srand((unsigned)time(0));
+
+ // Initialisation des noeuds du NN
+ delete [] node;
+ node = new unsigned char[nbOutput*3];
+ delete [] index;
+ index = new int[nbOutput];
+ delete [] freq;
+ freq = new int[nbOutput];
+
+ for(int i=0; i<nbOutput; i++)
+ {
+ // Remise à zéro de l'index et de freq
+ index[i] = i;
+ freq[i] = 0;
+
+ // Regeneration de nouveaux poids
+ WeightsGen (i);
+ }
+}
+
+
+/// Entraine un reseau de neurones
+void
+SegmLearn::TrainNN ()
+{
+ unsigned long pixelNum;
+ unsigned char *tabData;
+ int numOutputMax;
+
+ tabData = img->tabData;
+
+ for(long i=0; i<oconfig->nn_nil; i++)
+ {
+ // On choisit un pixel au hasard
+ pixelNum = (unsigned long)(img->nbPixels*(rand()/(RAND_MAX+1.0)));
+
+ numOutputMax = WinnerOutput (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->nn_sl*tabData[pixelNum*3+k])/(1+oconfig->nn_sl));
+
+ // 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++)
+ {
+ if (freq[k] < oconfig->nn_lazy_threshold)
+ // Regeneration de nouveaux poids
+ 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::GiveColor (unsigned char *x, bool testOutputMax, bool indexProcess)
+{
+ if (indexProcess)
+ return index [FindColorNN (x, testOutputMax)];
+ else
+ return FindColorNN (x, testOutputMax);
+}
+
+
+/// Entraine plusieurs reseaux de neurones avec des parametres differents et crees les images associees
+void
+SegmLearn::TestNN ()
+{
+
+/* double sl[] = {0.01, 0.1, 1};
+ unsigned long nil[] = {100, 1000, 10000, 100000, 1000000};
+ int nc[] = {3,4,5,6,7,8};
+
+ char filename[30];
+
+ // Parcours de toutes les valeurs de nombres de couleurs
+ for (int i_nc = 0; i_nc<6; i_nc++) {
+ BuildNN(nc[i_nc], 0);
+
+ // Parcours de toutes les valeurs de nombres d'itérations
+ for (int i_nil = 0; i_nil<5; i_nil++) {
+
+ oconfig->nn_nil = nil[i_nil];
+
+ // Parcours de toutes les valeurs de Step Learning
+ for (int i_sl = 0; i_sl<4; i_sl++) {
+ oconfig->nn_sl = sl[i_sl];
+
+ // Apprentissage du NN
+ TrainNN();
+
+ // Segmentation
+ Segm();
+
+ // Ecriture des résultats dans une image
+ sprintf(filename, "NN/%i-%f-%luNN.jpg", nc[i_nc], sl[i_sl], nil[i_nil]);
+ img->WriteSegm(filename, tabSegm);
+ sprintf(filename, "NN/%i-%f-%luNN", nc[i_nc], sl[i_sl], nil[i_nil]);
+ oconfig->node = node;
+ oconfig->CreateNNFile(filename, oconfig->colorMode, nbOutput);
+ }
+ }
+ }
+ */
+}