summaryrefslogtreecommitdiff
path: root/2004/i/nono/src/ovision/segmNN.cc
diff options
context:
space:
mode:
Diffstat (limited to '2004/i/nono/src/ovision/segmNN.cc')
-rw-r--r--2004/i/nono/src/ovision/segmNN.cc289
1 files changed, 84 insertions, 205 deletions
diff --git a/2004/i/nono/src/ovision/segmNN.cc b/2004/i/nono/src/ovision/segmNN.cc
index 9e4db20..5667e75 100644
--- a/2004/i/nono/src/ovision/segmNN.cc
+++ b/2004/i/nono/src/ovision/segmNN.cc
@@ -2,45 +2,42 @@
// 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 et apprentissage
-
+/// @file segmNN.cc Segmente l'image et cree un tableau contenant des valeurs segmentees, creation du reseau de neurones
#include "segmNN.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
-#include <math.h>
-#include <time.h>
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) {
- // Sauvegarde les pointeurs
- SegmNN::img = img;
+SegmNN::SegmNN (Img *img)
+{
+ this->img = img;
oconfig = OConfig::GetInstance ();
nbOutput = oconfig->nn_NbCouleurs;
node = NULL;
index = NULL;
- freq = NULL;
tabSegm = NULL;
}
+
/// Destructor SegmNN
-SegmNN::~SegmNN()
+SegmNN::~SegmNN ()
{
delete [] node;
delete [] index;
- delete [] freq;
delete [] tabSegm;
}
/// Affiche les poids du reseau de neurones (neural network : NN)
void
-SegmNN::ShowNodes()
+SegmNN::ShowNodes ()
{
// Affichage des poids du NN
cout << "Poids:";
@@ -50,14 +47,50 @@ SegmNN::ShowNodes()
}
+/// Renvoie la sortie ayant le plus haut niveau
+/// @param x couleur à segmentée
+int
+SegmNN::WinnerOutput (unsigned char *x)
+{
+ int output[nbOutput];
+ int numOutputMax = 0;
+ int tmp;
+
+ // Calcul des valeurs de sorties pour ce pixel
+ for(int j=0; j<nbOutput; j++)
+ {
+ output[j] = 0;
+
+ 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 luminosite on ajoute un poids sur son influence
+ if ((img->yuv && k==0) || (img->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)
+SegmNN::BuildNN (int nbOutput, int loadFromFile)
{
- SegmNN::nbOutput = nbOutput;
+ this->nbOutput = nbOutput;
// Permet de charger les poids du NN depuis un fichier ou en les initialisant aleatoirement
if (loadFromFile)
@@ -69,178 +102,74 @@ SegmNN::BuildNN(int nbOutput, int loadFromFile)
}
else
{
- // Charge les poids du NN et l'index des couleurs
+ // Charge les poids du NN
delete [] node;
node = new unsigned char[nbOutput*3];
for (int i = 0; i<nbOutput*3; i++)
node[i] = oconfig->node[i];
+
+ // Initialisation de l'index de couleur
delete [] index;
index = new int[nbOutput];
for (int i = 0; i<nbOutput; i++)
index[i] = oconfig->index[i];
- freq = new unsigned 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 unsigned int[nbOutput];
-
-
- for(int i=0; i<nbOutput; i++)
- {
- index[i] = i;
- freq[i] = 0;
-
- for(int j=0; j<3; j++)
- {
- // Attribution aléatoire des poids
- node[i*3+j] = (unsigned char) (255.0*rand()/(RAND_MAX+1.0));
- if (node[i*3+j] < 30) node[i*3+j] = 30;
- else if (node[i*3+j] > 220) node[i*3+j] = 220;
}
}
-}
-
-
-/// Entraine un reseau de neurones
-void
-SegmNN::TrainNN()
-{
- unsigned long pixelNum;
- unsigned char *tabData;
- int output[nbOutput];
- int numOutputMax=0;
-
- tabData = img->tabData;
- oconfig->colorMode = img->hsi*2 + img->yuv;
- oconfig->groupColor = 0;
-
- for(long i=0; i<oconfig->nn_nil; i++)
+ // Si on ne souhaite pas loader les poids a partir d'un fichier
+ else
{
- // On choisit un pixel au hasard
- pixelNum = (unsigned long)(img->nbPixels*(rand()/(RAND_MAX+1.0)));
-
- // Calcul des valeurs de sorties pour ce pixel
- for(int j=0; j<nbOutput; j++)
- {
- output[j] = 0;
-
- for(int k=0; k<3; k++)
- {
- if ((img->yuv && k==0) || (img->hsi && k==2))
- output[j] += abs((int)(oconfig->nn_influ_lum*node[j*3+k]-tabData[pixelNum*3+k])*abs(node[j*3+k]-tabData[pixelNum*3+k]));
- else
- output[j] += abs(node[j*3+k]-tabData[pixelNum*3+k])*abs(node[j*3+k]-tabData[pixelNum*3+k]);
- }
-
- // On cherche la sortie ayant le plus haut niveau
- if (output[j] < output[numOutputMax])
- numOutputMax = j;
- }
-
- // 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
- if ((i%300) == 299)
- {
- for (int k=0; k < nbOutput; k++)
- {
- if (freq[numOutputMax] < oconfig->nn_lazy_threshold)
- {
- // Regeneration de nouveaux poids
- for(int m=0; m<3; m++)
- {
- // Attribution aléatoire des poids
- node[numOutputMax*3+m] = (unsigned char) (255.0*rand()/(RAND_MAX+1.0));
- if (node[numOutputMax*3+m] < 30) node[numOutputMax*3+m] = 30;
- else if (node[numOutputMax*3+m] > 220) node[numOutputMax*3+m] = 220;
- }
- }
-
- // On remet le compteur a zero
- freq[k] = 0;
- }
-
- }
-
- }
-
- }
+ 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 testUndefined)
+SegmNN::FindColorNN (unsigned char *x, bool testOutputMax)
{
int numOutputMax=0;
int output[nbOutput];
- int j,tmp;
+ int tmp;
- // Calcul des valeurs de sorties pour ce pixel
- // si on est en yuv
- if (img->yuv)
+ // Calcul des valeurs de sorties du NN pour ce pixel
+ for(int j=0; j<nbOutput; j++)
{
- for(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]-x[0];
- output[j] = abs((int)(oconfig->nn_influ_lum*tmp*tmp));
- tmp = node[j*3+1]-x[1];
- output[j] += tmp*tmp;
- tmp = node[j*3+2]-x[2];
- output[j] += tmp*tmp;
-
- // On selectionne la sortie ayant la plus grande valeur comme couleur
- if (output[numOutputMax] > output[j])
- numOutputMax = j;
+ tmp = node[j*3+k]-x[k];
+
+ // Si on est en yuv ou hsi et que c'est la composante de luminosite, on ajoute un poids pour affecter son influence
+ if ((img->yuv && k==0) || (img->hsi && k==2))
+ output[j] += (int) oconfig->nn_influ_lum * tmp * tmp;
+ // Sinon calcul normal
+ else
+ output[j] += tmp * tmp;
}
- }
- // si on est en rgb
- else {
- for(j=0; j<nbOutput; j++)
- {
- output[j] = 0;
-
- for(int k=0; k<3; k++)
- output[j] += abs(node[j*3+k]-x[k])*abs(node[j*3+k]-x[k]);
- // On selectionne la sortie ayant la plus grande valeur comme couleur
- if (output[numOutputMax] > output[j])
- numOutputMax = j;
- }
- }
+ // On selectionne la sortie ayant la plus grande valeur comme couleur
+ if (output[numOutputMax] > output[j])
+ numOutputMax = j;
+ }
- if ((testUndefined) && (output[numOutputMax] > oconfig->nn_threshold_output))
+ // Test si la valeur de sortie est assez proche d'une couleur du rezo
+ if ((testOutputMax) && (output[numOutputMax] > oconfig->nn_threshold_output))
numOutputMax = UNDEFINED;
-
-// if (testUndefined) cout << output[numOutputMax] << endl;
+
return numOutputMax;
}
/// Segmente l'image avec le reseau de neurones
-void SegmNN::Segm()
+void
+SegmNN::Segm ()
{
-
unsigned char* tabData = img->tabData;
if (tabSegm) delete [] tabSegm;
@@ -250,14 +179,15 @@ void SegmNN::Segm()
// On recupere l'index et non le numero de sortie du NN
for (unsigned long i=0; i<img->nbPixels; i++)
{
- tabSegm[i] = index[FindColorNN(tabData+i*3)];
+ tabSegm[i] = index[FindColorNN (tabData+i*3)];
}
}
-/// Segmente l'image pour une seule couleur uniquement et permet donc d'isoler un ficher
+
+/// 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)
+SegmNN::Segm (int numColor)
{
unsigned char* tabData = img->tabData;
@@ -267,60 +197,9 @@ SegmNN::Segm(int numColor)
// Parcours de l'image pour la segmentation
for (unsigned long i=0; i<img->nbPixels; i++)
{
- if (FindColorNN(tabData+i*3) == numColor) tabSegm[i] = 1;
+ if (FindColorNN (tabData+i*3) == numColor) tabSegm[i] = 1;
else tabSegm[i] = 0;
}
}
-
-/*void
-SegmNN::InitCache ()
-{
-
-
-}
-*/
-
-
-/// Entraine plusieurs reseaux de neurones avec des parametres differents et crees les images associees
-void
-SegmNN::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);
- }
- }
- }
- */
-}