From 109db2b0cce1b89c75e32f3705a1c5975391b3c5 Mon Sep 17 00:00:00 2001 From: gaillaro Date: Sat, 1 May 2004 11:52:08 +0000 Subject: Ajout de ovision. --- 2004/i/nono/src/ovision/segmNN.cc | 260 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 2004/i/nono/src/ovision/segmNN.cc (limited to '2004/i/nono/src/ovision/segmNN.cc') diff --git a/2004/i/nono/src/ovision/segmNN.cc b/2004/i/nono/src/ovision/segmNN.cc new file mode 100644 index 0000000..d765f80 --- /dev/null +++ b/2004/i/nono/src/ovision/segmNN.cc @@ -0,0 +1,260 @@ +// 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 et apprentissage + +#include "segmNN.h" +#include +#include +#include +#include +using namespace std; + +/// Constructor SegmNN + +/// @param img classe img permettant d'acceder au donnees de l'image a traiter +/// @param config classe config permettant d'acceder aux variables de configuration +SegmNN::SegmNN(ImgFile *img, Config *config) { + // Sauvegarde les pointeurs + SegmNN::img = img; + SegmNN::config = config; + nbOutput = config->nn_NbCouleurs; + + node = NULL; + index = NULL; + tabSegm = NULL; +} + +/// Destructor SegmNN +SegmNN::~SegmNN() +{ +} + + +/// Affiche les poids du reseau de neurones (neural network : NN) +void SegmNN::ShowNodes() { + + // Affichage des poids du NN + cout << "Poids:"; + for(int i=0; inbNodeMax < nbOutput) { + cerr << "SegmNN::BuildNN : Nombre de nodes insuffisants dans le fichier poids\n"; + } + else { + // Charge les poids du NN et l'index des couleurs + node = config->node; + index = config->index; + } + return; + } + + //initialition de random + srand((unsigned)time(0)); + + // Initialisation des noeuds du NN + if (node) delete [] node; + node = new unsigned char[nbOutput*3]; + if (index) delete [] index; + index = new int[nbOutput]; + if (freq) delete [] freq; + freq = new unsigned int[nbOutput]; + + + for(int i=0; i 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; + config->colorMode = img->hsi*2 + img->yuv; + config->groupColor = 0; + + for(long i=0; inn_nil; i++) { + // 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; jyuv && k==0) || (img->hsi && k==2)) + output[j] += abs((int)(config->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] + config->nn_sl*tabData[pixelNum*3+k])/(1+config->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] < config->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; + } + + } + + } + + } +} + + +/// Renvoie le code de la couleur segmentee +/// @param *x pointeur vers un tableau contenant une valeur RGB +unsigned char SegmNN::FindColorNN(unsigned char *x) { + + int numOutputMax=0; + int output[nbOutput]; + int j; + + // Calcul des valeurs de sorties pour ce pixel + for(j=0; jyuv && k==0) || (img->hsi && k==2)) + output[j] += abs((int)(config->nn_influ_lum*node[j*3+k]-x[k])*abs(node[j*3+k]-x[k])); + else + 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; + } + } + + 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 un ficher +/// @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; + } +} + + +/// 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++) { + + config->nn_nil = nil[i_nil]; + + // Parcours de toutes les valeurs de Step Learning + for (int i_sl = 0; i_sl<4; i_sl++) { + config->nn_sl = sl[i_sl]; + + // Apprentissage du NN + TrainNN(); + + // Segmentation + Segm(); + + // Ecriture des résultats dans une image + sprintf(filename, "NN/%i-%lf-%luNN.jpg", nc[i_nc], sl[i_sl], nil[i_nil]); + img->WriteSegm(filename, tabSegm); + sprintf(filename, "NN/%i-%lf-%luNN", nc[i_nc], sl[i_sl], nil[i_nil]); + config->node = node; + config->CreateNNFile(filename, config->colorMode, nbOutput); + } + } + } +} -- cgit v1.2.3