summaryrefslogtreecommitdiff
path: root/2005/i
diff options
context:
space:
mode:
authorgaillaro2005-04-05 18:26:18 +0000
committergaillaro2005-04-05 18:26:18 +0000
commit97b69507c877a4644c0caac4f61e052e188f9d8e (patch)
tree1a81f341ab6577003fa60ca3fb135e7b4baeecba /2005/i
parent0062520c9cc87eeeb8828361bbb33033a6f07b7e (diff)
Renaissance de la vision :
- code standard robot - presque du C++ - apprentissage du RN sur plusieurs images - tableau de données couleurs compressé - reconnaissance de plusieurs objets possibles
Diffstat (limited to '2005/i')
-rw-r--r--2005/i/robert/src/ovision/see/Makefile.defs32
-rw-r--r--2005/i/robert/src/ovision/see/colorTable.cc88
-rw-r--r--2005/i/robert/src/ovision/see/colorTable.hh55
-rw-r--r--2005/i/robert/src/ovision/see/convertImg.cc98
-rw-r--r--2005/i/robert/src/ovision/see/convertImg.hh44
-rw-r--r--2005/i/robert/src/ovision/see/group.cc140
-rw-r--r--2005/i/robert/src/ovision/see/group.hh83
-rw-r--r--2005/i/robert/src/ovision/see/img.cc99
-rw-r--r--2005/i/robert/src/ovision/see/img.hh73
-rw-r--r--2005/i/robert/src/ovision/see/imgInterface.cc160
-rw-r--r--2005/i/robert/src/ovision/see/imgInterface.hh59
-rw-r--r--2005/i/robert/src/ovision/see/magnifier.cc167
-rw-r--r--2005/i/robert/src/ovision/see/magnifier.hh71
-rw-r--r--2005/i/robert/src/ovision/see/map.cc269
-rw-r--r--2005/i/robert/src/ovision/see/map.hh163
-rw-r--r--2005/i/robert/src/ovision/see/oconfig.cc238
-rw-r--r--2005/i/robert/src/ovision/see/oconfig.hh138
-rw-r--r--2005/i/robert/src/ovision/see/segm.cc84
-rw-r--r--2005/i/robert/src/ovision/see/segm.hh80
-rw-r--r--2005/i/robert/src/ovision/see/segmLearn.cc176
-rw-r--r--2005/i/robert/src/ovision/see/segmLearn.hh53
-rw-r--r--2005/i/robert/src/ovision/see/segmTable.cc30
-rw-r--r--2005/i/robert/src/ovision/see/segmTable.hh41
-rw-r--r--2005/i/robert/src/ovision/see/space.cc189
-rw-r--r--2005/i/robert/src/ovision/see/space.hh104
-rw-r--r--2005/i/robert/src/ovision/see/test_cam.cc36
-rw-r--r--2005/i/robert/src/ovision/see/test_colortable.cc49
-rw-r--r--2005/i/robert/src/ovision/see/test_group.cc55
-rw-r--r--2005/i/robert/src/ovision/see/test_img.cc22
-rw-r--r--2005/i/robert/src/ovision/see/test_magnifier.cc55
-rw-r--r--2005/i/robert/src/ovision/see/test_segm.cc32
31 files changed, 2983 insertions, 0 deletions
diff --git a/2005/i/robert/src/ovision/see/Makefile.defs b/2005/i/robert/src/ovision/see/Makefile.defs
new file mode 100644
index 0000000..42aed85
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/Makefile.defs
@@ -0,0 +1,32 @@
+PROGRAMS += test_ovision test_img test_group test_map test_ovisiontracker test_cam test_segm test_magnifier test_ovision test_colortable
+LIBS += $(ovision_OBJECTS)
+LDFLAGS= -Wall -g -fprofile-arcs -ftest-coverage -fmessage-length=0
+
+ovision_OBJECTS = convertImg.o img.o oconfig.o ovision.o segm.o imgInterface.o colorTable.o segmTable.o segmLearn.o group.o magnifier.o #space.o map.o
+
+test_img_OBJECTS = test_img.o img.o imgInterface.o oconfig.o $(image_OBJECTS)
+test_cam_OBJECTS = test_cam.o img.o imgInterface.o oconfig.o $(video4linux_OBJECTS) $(image_OBJECTS) $(utils_OBJECTS)
+test_segm_OBJECTS = test_segm.o img.o segm.o segmLearn.o oconfig.o imgInterface.o colorTable.o segmTable.o $(image_OBJECTS)
+test_ovision_OBJECTS = test_ovision.cc $(ovision_OBJECTS) $(image_OBJECTS) $(video4linux_OBJECTS) $(utils_OBJECTS)
+test_ovisionogl_OBJECTS = test_ovisionogl.o $(ovision_OBJECTS) $(image_OBJECTS) $(video4linux_OBJECTS) motor.o config.o serial.o
+test_ovisiontracker_OBJECTS = test_ovisiontracker.o $(ovision_OBJECTS) $(image_OBJECTS) $(video4linux_OBJECTS) motor.o date.o serial.o utils.o logger.o config.o
+test_map_OBJECTS = test_map.o $(ovision_OBJECTS) $(image_OBJECTS)
+test_dist_OBJECTS = test_dist.o $(ovision_OBJECTS)
+test_colortable_OBJECTS = test_colortable.o oconfig.o segmTable.o imgInterface.o img.o segm.o segmLearn.o colorTable.o $(image_OBJECTS)
+test_group_OBJECTS = test_group.o group.o img.o segm.o segmLearn.o oconfig.o imgInterface.o $(image_OBJECTS)
+test_magnifier_OBJECTS = test_magnifier.o magnifier.o group.o img.o segm.o segmLearn.o oconfig.o imgInterface.o $(image_OBJECTS)
+
+test_img: $(test_img_OBJECTS:%.o=%.o)
+test_cam: $(test_cam_OBJECTS:%.o=%.o)
+test_segm: $(test_segm_OBJECTS:%.o=%.o)
+ $(CXX) $(LDFLAGS) -lz $^ -o $@
+test_group: $(test_group_OBJECTS:%.o=%.o)
+test_magnifier: $(test_magnifier_OBJECTS:%.o=%.o)
+test_ovision: $(test_ovision_OBJECTS:%.o=%.o)
+ $(CXX) $(LDFLAGS) -lz $^ -o $@
+test_ovisionogl: $(test_ovisionogl_OBJECTS:%.o=%.o)
+test_ovisiontracker: $(test_ovisiontracker_OBJECTS:%.o=%.o)
+test_map: $(test_map_OBJECTS:%.o=%.o)
+test_dist: $(test_dist_OBJECTS:%.o=%.o)
+test_colortable: $(test_colortable_OBJECTS:%.o=%.o)
+ $(CXX) $(LDFLAGS) -lz $^ -o $@
diff --git a/2005/i/robert/src/ovision/see/colorTable.cc b/2005/i/robert/src/ovision/see/colorTable.cc
new file mode 100644
index 0000000..6d0780f
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/colorTable.cc
@@ -0,0 +1,88 @@
+// colorTable.cc - Classe tableau de couleur
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file colorTable.cc Gestion du tableau de couleur : compression/décompression, écriture, ...
+#include <iostream>
+#include <fstream>
+#include <zlib.h>
+
+#include "segmLearn.hh"
+#include "colorTable.hh"
+
+/// Constructor ColorTable
+ColorTable::ColorTable (const char *filename)
+ : data_ (0)
+{
+ load (filename);
+}
+
+
+/// Destructor ColorTable
+ColorTable::~ColorTable ()
+{
+ delete [] data_;
+}
+
+/// Cree un tableau des couleurs segmentées pour ne plus faire de calcul
+/// et augmenter la rapidité
+/// @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
+void
+ColorTable::create (const int nbOutput_, const bool testOutputMax)
+{
+ SegmLearn segm;
+ segm.buildNN (nbOutput_, Segm::loadFromFile);
+ std::cout << "ColorTable:: Creation de la table" << std::endl;
+ unsigned char x[3];
+ delete [] data_;
+ data_ = new unsigned char[colorTabSizeTotal];
+ // Parcours de toutes les valeurs possibles
+ for (int i=0; i<colorTabSize; i++)
+ for (int j=0; j<colorTabSize; j++)
+ for (int k=0; k<colorTabSize; k++)
+ {
+ // Remplissage de la table
+ x[0]=i; x[1]=j; x[2]=k;
+ data_[ i*colorTabSize2 + j*colorTabSize +k ] = segm.giveColor (x , testOutputMax);
+ }
+}
+
+/// Cree un fichier de ColorTable
+void
+ColorTable::save (const char *filename) const
+{
+ std::cout << "ColorTable:: Ecriture de la table" << std::endl;
+ gzFile file = gzopen (filename, "w+");
+ if (file)
+ {
+ gzwrite (file, (char*)data_, colorTabSizeTotal);
+ gzclose (file);
+ }
+ else
+ std::cerr << "ColorTable::CreateColorTableFile Erreur d'ouverture de fichier" << std::endl;
+
+}
+
+/// Charge un fichier de ColorTable
+bool
+ColorTable::load (const char *filename)
+{
+ /// Initialisation de data
+ delete [] data_;
+ data_ = new unsigned char[colorTabSizeTotal];
+ /// Ouverture du fichier de couleurs
+ gzFile file = gzopen (filename, "w+");
+ if (file)
+ {
+ std::cout << "ColorTable:: Chargement de la table" << std::endl;
+ gzread (file, (char*)data_, colorTabSizeTotal);
+ gzclose (file);
+ }
+ else
+ {
+ std::cerr << "ColorTable::CreateColorTableFile Erreur d'ouverture de fichier" << std::endl;
+ return false;
+ }
+ return true;
+}
+
diff --git a/2005/i/robert/src/ovision/see/colorTable.hh b/2005/i/robert/src/ovision/see/colorTable.hh
new file mode 100644
index 0000000..e8e95a5
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/colorTable.hh
@@ -0,0 +1,55 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef colorTable_h
+#define colorTable_h
+
+#include "segm.hh"
+
+/// Segmente l'image et cree un tableau contenant des valeurs segmentees, creation du reseau de neurones et apprentissage
+class ColorTable
+{
+ friend class SegmTable;
+ // Tableau de correspondance couleurs pixels -> couleur donnée par le rezo
+ unsigned char *data_;
+
+ public:
+ /// Constructeur
+ ColorTable (const char *filename = "rc/colortable.z");
+ /// Destructeur
+ virtual ~ColorTable ();
+ /// Cree un tableau des couleurs segmentées pour ne plus faire de calcul
+ void create(const int nbOutput, const bool testOutputMax = false);
+ /// Cree un fichier de ColorTable
+ void save (const char *filename = "rc/colortable.z") const;
+ /// Charge un fichier de ColorTable
+ bool load (const char *filename = "rc/colortable.z");
+ /// Constantes
+ static const int colorTabSize = 256;
+ static const int colorTabSize2 = colorTabSize*colorTabSize;
+ static const int colorTabSizeTotal = colorTabSize2*colorTabSize;
+ static const bool generate = false;
+ /// Operators
+ unsigned char operator [] (int num) {return data_[num];}
+};
+
+#endif // colorTable_h
diff --git a/2005/i/robert/src/ovision/see/convertImg.cc b/2005/i/robert/src/ovision/see/convertImg.cc
new file mode 100644
index 0000000..9bc87ea
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/convertImg.cc
@@ -0,0 +1,98 @@
+#include "convertImg.hh"
+
+#include <math.h>
+
+/// Renvoie le minimum entre 2 nombres
+inline unsigned char min (unsigned char a, unsigned char b)
+{
+ if (a<b) return a;
+ else return b;
+}
+
+/// Convertit un tableau de donnees RGB en YUV
+void
+ConvertImg::RGBtoYUV (Img &img)
+{
+ unsigned char r,g,b;
+ // Parcours du tableau et conversion des valeurs RGB en YUV
+ for (unsigned long i=0; i<img.nbPixels_; i++)
+ {
+ r = img.tabData_[i*3];
+ g = img.tabData_[i*3+1];
+ b = img.tabData_[i*3+2];
+ img.tabData_[i*3] = (unsigned char)(0.299*r + 0.587*g + 0.114*b); // Y
+ img.tabData_[i*3+1] = (unsigned char)(0-0.147*r - 0.289*g + 0.437*b + 0.5); // U
+ img.tabData_[i*3+2] = (unsigned char)(00.615*r - 0.515*g - 0.100*b + 0.5); // V
+ }
+ img.colorMode_ = Image::yuv;
+}
+
+/// Convertit un tableau de donnees RGB en YUV
+void
+ConvertImg::RGBtoHSI (Img &img)
+{
+ unsigned char r,g,b;
+ // Parcours du tableau et conversion des valeurs RGB en HSI
+ for (unsigned long i=0; i<img.nbPixels_; i++)
+ {
+ r = img.tabData_[i*3];
+ g = img.tabData_[i*3+1];
+ b = img.tabData_[i*3+2];
+ img.tabData_[i*3] = (unsigned char)(acos((r-0.5f*g-0.5f*b)/(sqrt(1.0f*(r-g)*(r-g)+(r-b)*(g-b))))); // H
+ img.tabData_[i*3+1] = (unsigned char)(1-min(min(r,g),b)); // S
+ img.tabData_[i*3+2] = (unsigned char)(0.33f*(r+g+b)); // I
+ }
+ img.colorMode_ = Image::hsi;
+}
+
+/// Convertit un tableau de donnees YUV en RGB
+void
+ConvertImg::YUVtoRGB (Img &img)
+{
+ unsigned char y,u,v;
+ // Parcours du tableau et conversion des valeurs YUV en RGB
+ for (unsigned long i=0; i<img.nbPixels_; i++) {
+ y = img.tabData_[i*3];
+ u = img.tabData_[i*3+1];
+ v = img.tabData_[i*3+2];
+ img.tabData_[i*3] = (unsigned char)(y + (1.4075 * (v - 128)));
+ img.tabData_[i*3+1] = (unsigned char)(y + ((0.3455 * (u - 128)) - (0.7169 * (v - 128))));
+ img.tabData_[i*3+2] = (unsigned char)(y + (1.7790 * (u - 128)));
+ }
+ img.colorMode_ = Image::rgb;
+}
+
+/// Convertit une image de BGR en RGB
+void
+ConvertImg::BGRtoRGB (Img &img)
+{
+ unsigned char b;
+ unsigned char *tab;
+ tab = img.tabData_;
+ // Parcours du tableau et conversion des valeurs BGR en RGB
+ for (unsigned long i=0; i<img.nbPixels_; i++)
+ {
+ b = *tab;
+ *tab = *(++(++tab));
+ *tab = b;
+ ++tab;
+ }
+ img.colorMode_ = Image::rgb;
+}
+
+/// Convertit une image en RGB
+void
+ConvertImg::ConvertToRGB (Img &img)
+{
+ switch (img.colorMode_)
+ {
+ case Image::bgr:
+ BGRtoRGB (img);
+ break;
+ case Image::yuv:
+ YUVtoRGB (img);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/2005/i/robert/src/ovision/see/convertImg.hh b/2005/i/robert/src/ovision/see/convertImg.hh
new file mode 100644
index 0000000..d2a80ef
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/convertImg.hh
@@ -0,0 +1,44 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef convertImg_h
+#define convertImg_h
+#include "img.hh"
+
+/// Conversion des images en RGB, YUV, HSI
+class ConvertImg
+{
+ public:
+ /// Conversion en YUV
+ void RGBtoYUV (Img &img);
+ /// Conversion en HSI
+ void RGBtoHSI (Img &img);
+ /// Conversion de YUV en RGB
+ void YUVtoRGB (Img &img);
+ /// Conversion de BGR en RGB
+ void BGRtoRGB (Img &img);
+ /// Conversion en RGB
+ void ConvertToRGB (Img &img);
+};
+
+#endif // convertImg_h
+
diff --git a/2005/i/robert/src/ovision/see/group.cc b/2005/i/robert/src/ovision/see/group.cc
new file mode 100644
index 0000000..56aaa55
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/group.cc
@@ -0,0 +1,140 @@
+// group.cc - Classe G
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file group.cc Cree une liste chainee de zones correspondant aux balles
+#include <iostream>
+#include <stdlib.h>
+#include <math.h>
+
+#include "group.hh"
+
+/// Constructeur
+/// @param *img classe image
+/// @param *segm classe segm
+Group::Group (Img *img, Segm *segm)
+ : segm_ (segm), img_ (img)
+{
+ oconfig_ = OConfig::getInstance ();
+}
+
+/// Ajoute une balle ou un poteau à la liste de groupes
+/// @param idColor numéro de la couleur du group
+/// @param xmin,xmax,ymin,ymax borne du group
+/// @param centerx, centery centre du group
+void
+Group::addZone (const int idColor, const int xmin, const int xmax, const int ymin, const int ymax)
+{
+ Zone zone;
+ zone.xmin = xmin; zone.xmax = xmax;
+ zone.ymin = ymin; zone.ymax = ymax;
+ zone.centerx = (xmax+xmin)/2;
+ zone.centery = (ymax+ymin)/2;
+
+ for (std::vector<ObjectColor>::iterator iter = oconfig_->groupColor.begin ();
+ iter != oconfig_->groupColor.end (); ++iter)
+ if (idColor == iter->color)
+ {
+ if (iter->label == "redSkittle") zone.id = redSkittle;
+ else if (iter->label == "greenSkittle") zone.id = greenSkittle;
+ else if (iter->label == "border") zone.id = border;
+ else if (iter->label == "base") zone.id = base;
+ else if (iter->label == "gap") zone.id = gap;
+ break;
+ }
+
+ zoneList_.push_back (zone);
+}
+
+/// Cherche l'objet complet a partir d'un pixel donne
+/// @param type type du group à rechercher GOAL ou BALL
+/// @param numColor numero de la couleur a chercher
+/// @param x,y coordonnees de depart pour la recherche
+void Group::plague (const unsigned char numColor, const int x, const int y)
+{
+ int xmax = x; int xmin = x;
+ int ymax = y; int ymin = y;
+
+ // TODO ajouter une inertie ?
+
+ int tmpY = y*img_->width_;
+ // Parcours de l'objet trouve de haut en bas et de gauche à droite
+ while ((xmax < img_->width_-1)&& (segm_->giveColor(img_->tabData_ + ((++xmax)+tmpY)*3, true, true) == numColor)) {}
+ while ((xmin > 0) && (segm_->giveColor(img_->tabData_ + ((--xmin)+tmpY)*3, true, true) == numColor)) {}
+ while ((ymax < img_->height_-1) && (segm_->giveColor(img_->tabData_ + (x+(++ymax)* img_->width_)*3, true, true) == numColor)) {}
+ while ((ymin > 0) && (segm_->giveColor(img_->tabData_ + (x+(--ymin)* img_->width_)*3, true, true) == numColor)) {}
+
+ // Ajout de la zone
+ addZone (numColor, xmin, xmax, ymin, ymax);
+}
+
+/// Affiche les zones trouvees
+void
+Group::showZones () const
+{
+ std::cout << "Groupes :\n";
+
+ if (!zoneList_.size ())
+ return;
+
+ for (std::vector<Zone>::const_iterator iter = zoneList_.begin (); iter != zoneList_.end (); ++iter)
+ std::cout << (int)iter->id << " " << iter->xmin << " " << iter->xmax << " "
+ << iter->ymin << " " << iter->ymax << "\n";
+ std::cout << std::endl;
+}
+
+
+/// Selectionne les points a tester dans l'image
+/// @param numColor numero de la couleur a trouver
+void Group::jumpPoints (int color)
+{
+ std::vector<ObjectColor> list;
+ ObjectColor obj;
+ obj.label = "undefined";
+ obj.color = color;
+ list.push_back (obj);
+ jumpPoints (list);
+}
+
+void Group::jumpPoints (const std::vector<ObjectColor> &colorList)
+{
+ zoneList_.clear ();
+ segm_->clearLum ();
+ segm_->setMode (img_->colorMode_);
+
+ int tmpY;
+ unsigned char curColor;
+ std::vector<ObjectColor>::const_iterator iter;
+ // Parcours d'une partie des pixels de l'image
+ for (int y=0; y<img_->height_; y+=oconfig_->jumpPointDist)
+ {
+ tmpY = y*img_->width_;
+ for (int x=0; x<img_->width_; x+=oconfig_->jumpPointDist)
+ {
+ curColor = segm_->giveColor (img_->tabData_ + ((tmpY + x) * 3), true, true);
+
+ for (iter = colorList.begin (); iter != colorList.end (); ++iter)
+ if ((iter->color >= 0) && (iter->color == curColor))
+ {
+ plague(curColor, x, y);
+ break;
+ }
+ }
+ }
+ std::cout << "<Group::jumpPoints> Luminosité : " << segm_->getLum () << std::endl;
+}
+
+/// Convertit le label de couleur en nombre
+std::string
+Group::translateToColorName (const int color)
+{
+ std::string label;
+ if (color == Group::redSkittle) label = "redSkittle";
+ else if (color == Group::greenSkittle) label = "greenSkittle";
+ else if (color == Group::gap) label = "gap";
+ else if (color == Group::border) label = "border";
+ else if (color == Group::base) label = "base";
+ else label = "undefined";
+ return label;
+}
+
diff --git a/2005/i/robert/src/ovision/see/group.hh b/2005/i/robert/src/ovision/see/group.hh
new file mode 100644
index 0000000..3aa0730
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/group.hh
@@ -0,0 +1,83 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef group_h
+#define group_h
+
+#include <vector>
+#include <string>
+#include "img.hh"
+#include "segm.hh"
+#include "oconfig.hh"
+
+/// Liste chainee des zones trouvees par la classe group
+struct Zone
+{
+ /// type de la zone
+ int id;
+ /// bornes de la zone pour x
+ int xmin, xmax;
+ /// bornes de la zone pour y
+ int ymin, ymax;
+ /// centre de la zone trouvee
+ int centerx, centery;
+ /// l'objet est vue partiellement ou completement
+ bool partial;
+ /// l'objet est situé en bas de l'image
+ bool bottom;
+};
+
+/// Cree une liste chainee de zones correspondant aux balles
+class Group
+{
+ /// Classe segmentation
+ Segm *segm_;
+ /// Classe image
+ Img *img_;
+ /// Classe oconfig
+ OConfig *oconfig_;
+ /// liste chainee pour sauver les zones des balles
+ std::vector<Zone> zoneList_;
+ /// Ajoute une balle ou un poteau à la liste de groupes
+ void addZone (const int id, const int xmin, const int xmax, const int ymin, const int ymax);
+ /// Cherche l'objet complet a partir d'un pixel
+ void plague (const unsigned char numColor, const int x, const int y);
+
+ public:
+ /// Type d'objects à trouver
+ static const int nbZoneType = 5;
+ enum ZoneType {greenSkittle, redSkittle, border, base, gap, undefined};
+ /// Convertit le label de couleur en nombre
+ static std::string translateToColorName (const int color);
+ /// Constructeur
+ Group (Img *img, Segm *segm);
+ /// Selectionne les points a tester
+ void jumpPoints(const std::vector<ObjectColor> &colorList);
+ void jumpPoints(int color);
+ /// Affiche les zones trouvees
+ void showZones() const;
+ /// Accessors
+ std::vector<Zone> &getZoneList () {return zoneList_;}
+};
+
+
+#endif // group_h
diff --git a/2005/i/robert/src/ovision/see/img.cc b/2005/i/robert/src/ovision/see/img.cc
new file mode 100644
index 0000000..5dd4d28
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/img.cc
@@ -0,0 +1,99 @@
+// img.cc - Classe Image
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file img.cc Chargement des images, conversion en YUV, HSI, detection des contours, transformation d'une image segmentee en RGB, ecriture de l'image sur le disque
+
+#include "img.hh"
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+
+/// Constructeur
+Img::Img (void)
+ : tabData_ (0), tabSegm_ (0)
+{
+}
+
+/// Destructeur
+Img::~Img (void)
+{
+ delete [] tabData_;
+ delete [] tabSegm_;
+}
+
+/// Ecrit les valeurs RGB dans un fichier
+void
+Img::writeRaw (const char *filename, unsigned char *tab) const
+{
+ if (!tab) tab = tabData_;
+ std::ofstream file (filename, std::ios::out | std::ios::trunc);
+ if (file)
+ file.write ((char *)tab, nbPixels_*3);
+ else
+ std::cerr << "Img::writeRaw Erreur d'ouverture de fichier" << std::endl;
+ file.close ();
+}
+
+/// Charge les valeurs RGB dans un fichier
+void
+Img::loadRaw (const char *filename, const Image::PixelFormat colorMode_, const int width_, const int height_)
+{
+ // Enregistre les paramètres de l'image
+ this->width_ = width_;
+ this->height_ = height_;
+ nbPixels_ = width_ * height_;
+ this->colorMode_ = colorMode_;
+ // Initialise tabData_
+ delete[] tabData_;
+ tabData_ = new unsigned char[nbPixels_*3];
+ // Ouvre l'image
+ std::ifstream file (filename, std::ios::in);
+ if (file)
+ file.read ((char *)tabData_, nbPixels_*3);
+ else
+ std::cerr << "Img::loadRaw Erreur d'ouverture de fichier " << filename << std::endl;
+ file.close ();
+}
+
+/// Charge plusieurs fichiers
+void
+Img::loadMultipeRaw (const std::vector<std::string> &imgList, const Image::PixelFormat colorMode_, const int width_, const int height_)
+{
+ // Enregistre les paramètres de l'image
+ this->width_ = width_;
+ this->height_ = height_ * imgList.size ();
+ nbPixels_ = width_ * height_;
+ this->colorMode_ = colorMode_;
+ // Initialise tabData_
+ delete[] tabData_;
+ tabData_ = new unsigned char[nbPixels_*3];
+ // Ouvre les images et stocke les données dans tabData_
+ for (std::vector<std::string>::const_iterator iter=imgList.begin(); iter != imgList.end(); iter++)
+ {
+ std::ifstream file (iter->c_str (), std::ios::in);
+ if (file)
+ file.read ((char *)tabData_, nbPixels_*3);
+ else
+ std::cerr << "Img::loadRaw Erreur d'ouverture de fichier " << *iter << std::endl;
+ file.close ();
+ }
+}
+
+
+/// Lit une image depuis un Image.
+void
+Img::load (ImageReader &loader)
+{
+ delete[] tabData_;
+ // Ouvre l'image
+ Image image;
+ image.read (loader);
+ image.getSize (width_, height_);
+ nbPixels_ = width_ * height_;
+ tabData_ = new unsigned char[image.getBufSize ()];
+ memcpy (tabData_, image.getBuf (), image.getBufSize ());
+ // Récupère le format de couleur
+ colorMode_ = image.getPixelFormat ();
+}
+
diff --git a/2005/i/robert/src/ovision/see/img.hh b/2005/i/robert/src/ovision/see/img.hh
new file mode 100644
index 0000000..ac5fd14
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/img.hh
@@ -0,0 +1,73 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef img_h
+#define img_h
+#include <vector>
+#include <string>
+
+#include "image/image.hh"
+#include "image/image_reader.hh"
+#include "oconfig.hh"
+
+/// Chargement des images, conversion en YUV, HSI, detection des contours,
+/// transformation d'une image segmentee en RGB, ecriture de l'image sur le disque
+class Img
+{
+ friend class ConvertImg;
+ friend class Group;
+ friend class Magnifier;
+ friend class SegmLearn;
+ friend class Segm;
+ friend class Comm;
+ friend class Live;
+
+ public:
+ /// Constructeur
+ Img (void);
+ /// Destructeur
+ ~Img (void);
+ /// Ecrite des valeurs RGB dans un fichier
+ void writeRaw (const char *filename, unsigned char *tab = 0) const;
+ /// Charge les valeurs RGB à partir d'un fichier
+ void loadRaw (const char *filename, const Image::PixelFormat colorMode, const int width, const int height);
+ /// Charge plusieurs fichiers
+ void loadMultipeRaw (const std::vector<std::string> &imgList, const Image::PixelFormat colorMode, const int width, const int height);
+ /// Lit une image depuis un Image.
+ void load (ImageReader &loader);
+
+ protected:
+ /// tableau des couleurs bruts
+ unsigned char *tabData_;
+ /// tableau avec couleurs segmentees
+ unsigned char *tabSegm_;
+ /// dimension de l'image
+ int height_, width_;
+ /// nombres de pixels de l'image
+ unsigned long nbPixels_;
+ /// mode de l'espace de couleurs
+ Image::PixelFormat colorMode_;
+};
+
+
+
+#endif // img_h
diff --git a/2005/i/robert/src/ovision/see/imgInterface.cc b/2005/i/robert/src/ovision/see/imgInterface.cc
new file mode 100644
index 0000000..bafe0b3
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/imgInterface.cc
@@ -0,0 +1,160 @@
+
+/// @file imgInterface.cc Chargement des images, conversion en YUV, HSI, detection des contours, transformation d'une image segmentee en RGB, ecriture de l'image sur le disque
+
+#include "imgInterface.hh"
+#include <iostream>
+#include <vector>
+
+const unsigned char ImgInterface::tabCol_[9][3] =
+ {{0, 0, 0}, {255, 255, 255},{0, 0, 255},
+ {0,255,0}, {255, 0, 0}, {0, 150, 60},
+ {150,60,0}, {0, 150, 60}, {20, 50, 120}};
+
+/// Constructeur
+ImgInterface::ImgInterface ()
+ : tabOut_ (0)
+{}
+
+/// Cree un tableau en RGB pour l'affichage a partir d'une image segmentee
+/// @param *tabIn pointeur vers un tableau de donnees segmentees
+/// @param *tabOut_ pointeur vers un tableau de donnees RGB
+void
+ImgInterface::doImg (const unsigned char *tabIn)
+{
+ /// Initialise les données
+ if (!tabIn) tabIn = tabSegm_;
+ delete [] tabOut_;
+ tabOut_ = new unsigned char [nbPixels_ * 3];
+ /// Remplissage de tabOut
+ if (tabIn)
+ {
+ // Change les couleurs segmentees en valeurs RGB pour l'affichage
+ for (int i=0; i<(int)(nbPixels_);i++)
+ {
+ tabOut_[i*3] = tabCol_[tabIn[i]][0];
+ tabOut_[i*3+1] = tabCol_[tabIn[i]][1];
+ tabOut_[i*3+2] = tabCol_[tabIn[i]][2];
+ }
+ }
+ else
+ {
+ // Si la table donnee est vide on renvoie des couleurs noires
+ for (int i=0; i<(int)(nbPixels_);i++)
+ {
+ tabOut_[i*3] = 0;
+ tabOut_[i*3+1] = 0;
+ tabOut_[i*3+2] = 0;
+ }
+ }
+}
+
+
+/// Dessine les contours autour d'un objet
+void
+ImgInterface::drawBox (unsigned char *tab, const std::vector<Zone> &list)
+{
+ unsigned char *pTabMin, *pTabMax;
+ // Parcours de la liste des groupes
+ for (std::vector<Zone>::const_iterator iter = list.begin (); iter != list.end (); ++iter)
+ {
+ // Affiche les coutours horizontaux
+ pTabMin = &tab[iter->ymin*width_+iter->xmin];
+ pTabMax = &tab[iter->ymax*width_+iter->xmin];
+ for (int x=iter->xmin; x<iter->xmax; x++)
+ {
+ *pTabMin = 1;
+ *pTabMax = 1;
+ ++pTabMin;
+ ++pTabMax;
+ }
+ // Affiche les courtours verticaux
+ pTabMin = &tab[iter->ymin*width_+iter->xmin];
+ pTabMax = &tab[iter->ymin*width_+iter->xmax];
+ for (int x=iter->ymin; x<iter->ymax; x++)
+ {
+ *pTabMin = 1;
+ *pTabMax = 1;
+ pTabMin += width_;
+ pTabMax += width_;
+ }
+
+ // Affiche une croix au centre
+ pTabMin = &tab[iter->centery*width_+iter->centerx-5];
+ pTabMax = &tab[(iter->centery-5)*width_+iter->centerx];
+ for (int x=0; x<10; x++)
+ {
+ *pTabMin = 1;
+ *pTabMax = 1;
+ ++pTabMin;
+ pTabMax += width_;
+ }
+ }
+}
+
+/// Ajoute des coutours autour des objets trouvées
+void
+ImgInterface::addGroupToDisplay (unsigned char *tab, const std::vector<Zone> &list)
+{
+ if (!tab)
+ {
+ std::cerr << "ImgInterface::AddGroupToDisplay tab empty" << std::endl;
+ return;
+ }
+ drawBox (tab, list);
+}
+
+
+/// Mirroir l'image
+void
+ImgInterface::mirror ()
+{
+ const int totalWidth = width_*3;
+ unsigned char buf[totalWidth];
+ /// Inverse l'image
+ for (int i=0; i<height_; ++i)
+ {
+ memcpy (buf, &tabData_[i*totalWidth], totalWidth);
+ for (int j=0; j<width_; ++j)
+ {
+ tabData_[i*totalWidth+j*3+2] = buf[totalWidth-j*3+2];
+ tabData_[i*totalWidth+j*3+1] = buf[totalWidth-j*3+1];
+ tabData_[i*totalWidth+j*3] = buf[totalWidth-j*3];
+ }
+ }
+}
+
+/// Creation du tableau de RGB pour faire une image
+void
+ImgInterface::doGroupImg (const std::vector<Zone> &zoneList, bool init)
+{
+ // On verifie que des groupes ont ete trouve
+ if (zoneList.empty ()) {
+ std::cerr << "ImgInterface::doGroupImg: No group defined" << std::endl;
+ delete [] tabSegm_;
+ tabSegm_ = 0;
+ return;
+ }
+ if (init)
+ {
+ // Allocation de la memoire
+ delete [] tabSegm_;
+ tabSegm_ = new unsigned char[nbPixels_];
+ // On initialise le tableau pour une image noire
+ for (unsigned int i=0; i<nbPixels_; i++)
+ tabSegm_[i] = 0;
+ }
+ else
+ {
+ // Allocation de la memoire
+ if (!tabSegm_)
+ tabSegm_ = new unsigned char[nbPixels_];
+ }
+ // Parcours de la liste des zones trouvees
+ for (std::vector<Zone>::const_iterator iter = zoneList.begin ();
+ iter < zoneList.end (); ++iter)
+ // Remplissage de la zone avec une couleur
+ for(int i=iter->xmin; i<iter->xmax; i++)
+ for (int j=iter->ymin; j<iter->ymax; j++)
+ tabSegm_[j*width_+i] = iter->id+1;
+ std::cout << std::endl;
+}
diff --git a/2005/i/robert/src/ovision/see/imgInterface.hh b/2005/i/robert/src/ovision/see/imgInterface.hh
new file mode 100644
index 0000000..0117eef
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/imgInterface.hh
@@ -0,0 +1,59 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef imgInterface_h
+#define imgInterface_h
+
+#include "img.hh"
+#include "group.hh"
+
+/// Chargement des images, conversion en YUV, HSI, detection des contours,
+/// transformation d'une image segmentee en RGB, ecriture de l'image sur le disque
+class ImgInterface : public Img
+{
+ /// Image des groupes
+ unsigned char *tabOut_;
+ /// tableau de couleur utlisation pour la creation de l'image segmentee
+ static const unsigned char tabCol_[][3];
+
+ public:
+ ImgInterface ();
+ /// Destructeur
+ ~ImgInterface (void) {};
+ /// Transformation d'un tableau de valeurs segmentees en RGB
+ void doImg (const unsigned char *tabIn = 0);
+ /// Ajoute les coutours autour des balles trouvées
+ void addGroupToDisplay (unsigned char *tab, const std::vector<Zone> &list);
+ /// Mirroir l'image
+ void mirror ();
+ /// Creation du tableau de RGB pour faire une image
+ void doGroupImg (const std::vector<Zone> &zoneList, bool init=true);
+ ///
+ unsigned char* getTabOut () {return tabOut_;}
+ unsigned char* getTabSegm () {return tabSegm_;}
+
+ private:
+ /// Dessine des contours autour d'un objet
+ void drawBox (unsigned char *tab, const std::vector<Zone> &list);
+};
+
+#endif // imgInterface_h
diff --git a/2005/i/robert/src/ovision/see/magnifier.cc b/2005/i/robert/src/ovision/see/magnifier.cc
new file mode 100644
index 0000000..067bae3
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/magnifier.cc
@@ -0,0 +1,167 @@
+// magnifier.cc - Classe Magnifier
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+#include <iostream>
+
+#include "magnifier.hh"
+
+/// Constructeur
+Magnifier::Magnifier (Img *img, Segm *segm)
+ : segm_ (segm), img_ (img)
+{
+ oconfig_ = OConfig::getInstance ();
+ itemList_ = new std::vector<Zone>[Group::nbZoneType];
+}
+
+/// Destructeur
+Magnifier::~Magnifier (void)
+{
+ delete [] itemList_;
+}
+
+
+// XXX getdelta XXX
+/// Retourne le delta utilisé pour la dissociation de 2 balles proches
+/// @param type type du group à rechercher GOAL ou BALL
+/// @param y coordonnees de la hauteur de la balle
+/*int
+Group::GetDelta (int type, int y)
+{
+ if (type == BALL)
+ return (int)(25 + y*0.1);
+
+ else return 3*(int)(25 + y*0.1);
+}
+*/
+
+/// Analyse une liste de zones
+/// @param zoneList liste des zones extraites par la classe group
+void
+Magnifier::analyse (const std::vector<Zone> &zoneList)
+{
+ // remise à zéro de toutes les listes
+ for (int i=0; i<Group::nbZoneType; ++i)
+ itemList_[i].clear ();
+ // parcours de toutes les zones extraites
+ for(std::vector<Zone>::const_iterator iter = zoneList.begin (); iter != zoneList.end (); ++iter)
+ {
+ // on vire si trop petit
+ // XXX test avec l'aire ?
+ //if (((iter->xmax - (iter->xmin)) * (iter->ymax - iter->ymin)) < oconfig_->
+ if (((iter->xmax - iter->xmin) < oconfig_->minLengthZone)
+ || ((iter->ymax - iter->ymin) < oconfig_->minLengthZone))
+ continue;
+ // Vérifie qu'il n'y a pas de doublon
+ if (!checkIsUnique (*iter))
+ continue;
+ switch (iter->id)
+ {
+ case Group::redSkittle:
+ if (isRedSkittle (*iter)) addItem (*iter);
+ break;
+ case Group::greenSkittle:
+ if (isGreenSkittle (*iter)) addItem (*iter);
+ break;
+ case Group::base:
+ if (isBase (*iter)) addItem (*iter);
+ break;
+ case Group::gap:
+ if (isGap (*iter)) addItem (*iter);
+ break;
+ case Group::border:
+ if (isBorder (*iter)) addItem (*iter);
+ break;
+ }
+ }
+}
+
+
+/// Test si l'object s'agit d'un doublon
+bool
+Magnifier::checkIsUnique (const Zone &zone)
+{
+ const int uniqueness = 50;
+ for (std::vector<Zone>::iterator iter = itemList_[zone.id].begin ();
+ iter != itemList_[zone.id].end (); ++iter)
+ if ((abs (zone.centerx - iter->centerx) < uniqueness)
+ || (abs (zone.centery - iter->centery) < uniqueness))
+ {
+ // on met a jour les données de l'item déjà trouvé
+ if (zone.xmin < iter->xmin) iter->xmin = zone.xmin;
+ if (zone.ymin < iter->ymin) iter->ymin = zone.ymin;
+ if (zone.xmax > iter->xmax) iter->xmax = zone.xmax;
+ if (zone.ymax > iter->ymax) iter->ymax = zone.ymax;
+
+ iter->centerx = (iter->xmax - iter->xmin) / 2;
+ iter->centery = (iter->ymax - iter->ymin) / 2;
+ return false;
+ }
+ return true;
+}
+
+/// Test si l'objet est une quille rouge
+bool
+Magnifier::isRedSkittle (const Zone &zone) const
+{
+ return true;
+}
+
+/// Test si l'objet est une bordure
+bool
+Magnifier::isBorder (const Zone &zone) const
+{
+ // test si la zone touche au moins deux bords de l'image
+ /// XXX pas tout à fait vrai près du fossé
+ unsigned count = 0;
+ if (zone.xmin <= 0) ++count;
+ if (zone.ymin <= 0) ++count;
+ if (zone.xmax >= img_->width_) ++count;
+ if (zone.ymax <= img_->height_) ++count;
+ if (count < 2) return false;
+ return true;
+}
+
+
+/// Test si l'objet est une quille verte
+bool
+Magnifier::isGreenSkittle (const Zone &zone) const
+{
+ return true;
+}
+
+/// Test si l'objet est un socle
+bool
+Magnifier::isBase (const Zone &zone) const
+{
+ return true;
+}
+
+/// Test si l'objet est un fossée
+bool
+Magnifier::isGap (const Zone &zone) const
+{
+ return true;
+}
+
+/// Ajout d'un objet
+
+void
+Magnifier::addItem (const Zone &zone)
+{
+ // TODO remplir les flags
+
+ itemList_[zone.id].push_back (zone);
+}
+
+
+/// Affiche les zones trouvees après analyse
+void
+Magnifier::showItems (const Group::ZoneType type) const
+{
+ std::cout << "Items :\n";
+ for (std::vector<Zone>::const_iterator iter = itemList_[type].begin (); iter != itemList_[type].end (); ++iter)
+ std::cout << (int)iter->id << " " << iter->xmin << " " << iter->xmax << " "
+ << iter->ymin << " " << iter->ymax << "\n";
+ std::cout << std::endl;
+}
diff --git a/2005/i/robert/src/ovision/see/magnifier.hh b/2005/i/robert/src/ovision/see/magnifier.hh
new file mode 100644
index 0000000..1d7aa67
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/magnifier.hh
@@ -0,0 +1,71 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef magnifier_h
+#define magnifier_h
+
+#include <vector>
+
+#include "segm.hh"
+#include "oconfig.hh"
+#include "group.hh"
+#include "img.hh"
+
+/// Filtre la liste d'objets trouvées
+class Magnifier
+{
+ /// Classe segmentation
+ Segm *segm_;
+ /// Classe oconfig
+ OConfig *oconfig_;
+ /// Classe img
+ Img *img_;
+ /// Liste des objects après analyse
+ std::vector<Zone> *itemList_;
+
+ public:
+ /// Constructeur
+ Magnifier (Img *img, Segm *segm);
+ /// Destructeur
+ ~Magnifier (void);
+ /// Analyse une liste de zones
+ void analyse (const std::vector<Zone> &zoneList);
+ /// Affiche les zones trouvees après analyse
+ void showItems (const Group::ZoneType type) const;
+ /// Renvoie une liste d'objet
+ std::vector<Zone>& getItemList (Group::ZoneType type)
+ {return itemList_[type];}
+
+ private:
+ /// Ajout d'un objet
+ void addItem (const Zone &zone);
+ /// Test si l'object s'agit d'un doublon
+ bool checkIsUnique (const Zone &zone);
+ /// Test la validité des objects
+ bool isRedSkittle (const Zone &zone) const;
+ bool isGreenSkittle (const Zone &zone) const;
+ bool isBase (const Zone &zone) const;
+ bool isBorder (const Zone &zone) const;
+ bool isGap (const Zone &zone) const;
+};
+
+#endif // magnifier_h
diff --git a/2005/i/robert/src/ovision/see/map.cc b/2005/i/robert/src/ovision/see/map.cc
new file mode 100644
index 0000000..a05563a
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/map.cc
@@ -0,0 +1,269 @@
+// map.cc - Classe Map
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file map.cc Fourni la liste des balles presentes sur le terrain et permet le choix rapide et efficace de la prochaine balle a aller chercher
+
+#include "map.hh"
+#include <iostream>
+#include <math.h>
+using namespace std;
+
+
+#define TABLE_WIDTH 2100
+#define TABLE_HEIGHT 2400
+
+
+/// Constructeurs.
+Map::Map (Space *space)
+ : lock = 0; treeFound (0), checkCurBall (0)
+// : motor (Motor::getInstance ()), tracker (motor.getTracker ())
+{
+
+ oconfig = OConfig::GetInstance ();
+
+ Map::oconfig = oconfig;
+ Map::space = space;
+
+ posGoal[0] = 105;
+ posGoal[1] = 0;
+}
+
+/// Destructeur.
+Map::~Map (void)
+{
+}
+
+
+/// Donne la position dans le référentiel de la table
+void
+Map::GetPosFromLoc (int locImgX, int locImgY, double &posX, double &posY)
+{
+ double locX, locY;
+ double posRobotX, posRobotY, angleRobot;
+
+ space->GetLoc(locImgX, locImgY, locX, locY);
+ // tracker.getPos(posRobotX, posRobotY, angleRobot);
+ space->GetPos(locX, locY, posRobotX, posRobotY, angleRobot, posX, posY);
+}
+
+/// Ajoute une balle a la map
+void
+Map::AddBall(double *pos, ZONE *pZone)
+{
+ tBALL ballTmp;
+
+ ballTmp.position[0] = pos[0];
+ ballTmp.position[1] = pos[1];
+
+ // definit la position de la balle
+ // ballTmp.zone = (double)((int)(pos[0])%300 + ((int)(pos[1])%300)*7);
+
+ // Vue de la balle partiel ou en bas de l'ecran
+ ballTmp.partial = pZone->partial;
+ if (pZone->bottom)
+ ballTmp.bottom = oconfig->ball_bottom_time_out ;
+ else ballTmp.bottom = 0;
+
+ ballTmp.skepticism = 0;
+ ballTmp.precision = pZone->centery;
+
+ // calcul du score partie
+ ballTmp.preScore = 0;
+// oconfig->distance_ball_goal_weight * Dist (pos, posGoal);
+
+ ball.push_back(ballTmp);
+}
+
+/// Supprime une balle de la map
+void
+Map::DelBall(list<tBALL>::iterator &iter)
+{
+ ball.erase(iter);
+ checkCurBall = 0;
+}
+
+/// Test si une balle trouvee correspond a une balle de la map
+int
+Map::TestSimilarBall(ZONE *pBall, list<tBALL>::iterator &iter)
+{
+ // Parcours de toutes les balles déjà trouvées
+ for(iter = ball.begin(); iter != ball.end(); iter++)
+ {
+ double pos[2] = {pBall->centerx, pBall->centery};
+ if (Dist(iter->position, pos) < ((iter->partial || pBall->partial)?oconfig->map_error_part:oconfig->map_error))
+ return 1;
+ }
+
+ return 0;
+}
+
+/// Calcul de distance
+double
+Map::Dist(double pos1X, double pos1Y, double pos2X, double pos2Y)
+{
+ double x = pos2X - pos1X;
+ double y = pos2Y - pos1Y;
+ return sqrt((double)(x * x + y * y));
+}
+
+double
+Map::Dist(double *pos1, double *pos2)
+{
+ double x = pos2[0]-pos1[0];
+ double y = pos2[1]-pos1[1];
+ return sqrt((double)(x * x + y * y));
+}
+
+
+double
+Map::Angle (double ballPosY, double robotPosY, double distRobotBall)
+{
+ return acos ((ballPosY - robotPosY)/distRobotBall);
+}
+
+/// Balle lockée ?
+bool
+Map::IsLock()
+{
+ return lock;
+}
+
+/// Lock ou unlock une balle pour savoir quel balle le robot suit
+void
+Map::SetLock(bool value)
+{
+ lock = value;
+}
+
+
+/// Donne la position de la balle la plus proche ou locke
+bool
+Map::GetCurBallPos (double &x, double &y)
+{
+ if (checkCurBall == true)
+ {
+ x = curBall->position[0] + 35;
+ y = curBall->position[1];
+ cout << "position balle: " << x << " " << y << endl;
+ return 1;
+ }
+ return false;
+}
+
+
+/// Retourne si un palmier est sur l'image
+bool
+Map::IsTree ()
+{
+ return treeFound;
+}
+
+
+/// Donne la position du palmier à l'image
+bool
+Map::GetTreePos (double &x, double &y)
+{
+ if (treeFound == true)
+ {
+ x = posTree[0];
+ y = posTree[1];
+ return 1;
+ }
+ return 0;
+}
+
+/// Met a jour la map avec une nouvelle liste de balle
+void
+Map::AddBallsToMap(Group *group)
+{
+ ZONE *pCur = group->zoneListBall;
+ double pos[2];
+ double centYMax = 900;
+
+
+ // On supprime l'ancienne liste de balle
+ ball.clear ();
+ checkCurBall = 0;
+
+ while (pCur)
+ {
+ //XXX a enlever XXX
+ pCur->centery = 296 - pCur->centery;
+
+ // On choppe la position par rapport au robot
+ space->GetLoc (pCur->centerx, pCur->centery, pos[0], pos[1]);
+
+ AddBall(pos, pCur);
+ checkCurBall = 1;
+
+ // Place la balle la plus proche dans le pointeur curBall
+ if (pCur->centery < centYMax)
+ {
+ curBall = ball.end ();
+ curBall--;
+ centYMax = pCur->centery;
+ }
+ pCur = pCur->next;
+ }
+
+ // Detection de poteau ou de goal
+ pCur = group->zoneListGoal;
+ if (pCur)
+ {
+ treeFound = 1;
+ space->GetLoc (pCur->centerx, pCur->ymax, posTree[0], posTree[1]);
+ }
+ else
+ treeFound = 0;
+}
+
+/// Met a jour les scores
+void
+Map::UpdateMap()
+{
+ double robotPosX, robotPosY;//, robotAngle;
+ double distRobotBall;
+
+ // On met a jour tous les scores
+ list<tBALL>::iterator iter;
+ for(iter = ball.begin(); iter != ball.end(); iter++)
+ {
+ distRobotBall = Dist(robotPosX, robotPosY, iter->position[0], iter->position[1]);
+
+ iter->score = iter->preScore
+ + oconfig->distance_ball_robot_weight * distRobotBall
+// + oconfig->angle_ball_weight * abs (robotAngle - Angle (iter->position[2], robotPosY, distRobotBall));
+ // + oconfig->ball_density_weight *
+ // + oconfig->ennemy_presence_weight *
+ + oconfig->skepticism_weight * iter->skepticism;
+ // + oconfig->ball_precision_weight *
+ // + ... iter->partial;
+
+ if (checkCurBall)
+ if ((!IsLock()) && (iter->score > curBall->score))
+ {
+ curBall = iter;
+ checkCurBall = 1;
+ }
+ }
+}
+
+
+/// Affiche les balles de la map
+void
+Map::ShowBalls()
+{
+ list<tBALL>::iterator iter;
+ int i=0;
+ cout << "balles: (" << ball.size () << ")" << endl;;
+
+ /// Parcours de la liste
+ for(iter = ball.begin(); iter != ball.end(); iter++)
+ {
+ /// Affichage des infos de la balle
+ cout << i << ": " << iter->position[0] << "\t" << iter->position[1] << endl;
+ i++;
+ }
+ cout << endl;
+}
diff --git a/2005/i/robert/src/ovision/see/map.hh b/2005/i/robert/src/ovision/see/map.hh
new file mode 100644
index 0000000..dca9ee0
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/map.hh
@@ -0,0 +1,163 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+
+#ifndef map_h
+#define map_h
+
+#include <list>
+#include "group.hh"
+#include "oconfig.hh"
+#include "space.hh"
+#include "motor/motor.hh"
+
+
+#define LOCKED 1
+#define UNLOCKED 0
+
+
+/// Structure stockant les balles
+struct tBALL {
+ /// position de la balle
+ double position[2];
+
+ /// score balle pour le choix de la prochaine balle a aller chercher
+ double score;
+
+ /// score precalcule sans distance pour eviter les calculs redondants
+ double preScore;
+
+ // zone balle, facilite le calcul de la distance robot-balle
+ int zone;
+
+ /// probabilite que la balle sot a la zone indique par la map
+ int skepticism;
+
+ /// balle vu seulement partiellement par la camera
+ bool partial;
+
+ /// précision de la position de la balle pour mettre à jour sa position
+ int precision;
+
+ /// marqueur pour savoir si la balle a quitte le champ de vision par le bas
+ int bottom;
+};
+
+
+/// Classe Map
+class Map
+{
+ /// Variables configurables
+ OConfig *oconfig;
+ Space *space;
+// Motor &motor;
+// const Tracker &tracker;
+
+ /// position des goals
+ double posGoal[2];
+
+ /// Liste de balles trouvees
+ std::list<tBALL> ball;
+
+ /// balle locke ?
+ bool lock;
+
+ /// Palmier sur l'image ?
+ bool treeFound;
+
+ /// Position du palmier à l'écran
+ double posTree[2];
+
+ /// Ajoute une balle a la map
+ void AddBall(double *pos, ZONE *pZone);
+
+ /// Supprime une balle de la map
+ void DelBall(std::list<tBALL>::iterator &iter);
+
+ /// Test si une balle trouvà correspond a une balle de la map
+ int TestSimilarBall(ZONE *pBall , std::list<tBALL>::iterator &iter);
+
+ /// Distance robot-balle
+ double Dist(double *pos1, double *pos2);
+ double Dist(double pos1X, double pos1Y, double pos2X, double pos2Y);
+
+ /// Calcul de l'angle robot-balle
+ double Angle (double ballPosY, double robotPosY, double distRobotBall);
+
+ /// Balle ayant le plus haut score
+ std::list<tBALL>::iterator curBall;
+
+ /// Permet de savoir si une balle est dans curBall
+ bool checkCurBall;
+
+ public:
+
+ /// Balle ayant la plus grand score
+ int goodBall;
+
+ /// Zone ou est situe le robot
+ int zoneRobot;
+
+ /// Constructeurs.
+ Map (Space *space);
+
+ /// Destructeur.
+ ~Map (void);
+
+ /// Retourne si une balle est locke
+ bool IsLock ();
+
+ /// Lock une balle pour savoir quel balle le robot suit
+ void SetLock (bool value);
+
+ /// Presence de palmier sur l'image
+ bool IsTree ();
+
+ /// Ajoute des balles a la liste
+ void AddBallsToMap (Group *group);
+
+ /// Met a jour les scores des balles
+ void UpdateMap ();
+
+ //Affiche les balles de la map
+ void ShowBalls ();
+
+ /// Donne la position du 1er arbre trouvé sur la map
+ bool GetTreePos (double &x, double &y);
+
+ /// Accessors
+ /// Renvoie l'iterator sur la balle courante
+ const std::list<tBALL>::iterator &GetCurBall ();
+
+ /// Donne la position de la balle la plus proche ou locke
+ /// Retourne NULL si la balle locke est perdu
+ bool GetCurBallPos (double &x, double &y);
+
+ /// Donne la position dans le référentiel de la table
+ void GetPosFromLoc (int locImgX, int locImgY, double &posX, double &posY);
+
+ protected:
+};
+
+
+#endif // map_h
diff --git a/2005/i/robert/src/ovision/see/oconfig.cc b/2005/i/robert/src/ovision/see/oconfig.cc
new file mode 100644
index 0000000..784d031
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/oconfig.cc
@@ -0,0 +1,238 @@
+// config.cc - Classe OConfig
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file config.cc Charge le fichier config et distribue les variables
+
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sstream>
+
+#include "oconfig.hh"
+
+OConfig *OConfig::instance = 0;
+
+/// Constructor
+/// @param *filename nom du fichier de config
+OConfig::OConfig(const char *filename)
+ : node (0), color (0), index (0)
+{
+ instance = this;
+ load (filename);
+ loadNNFile("rc/poids");
+ loadDistFile("rc/dist");
+}
+
+/// Destructor
+OConfig::~OConfig()
+{
+}
+
+/// Parse une ligne du fichier de config
+/// @param *var nom de la variable a fixer
+/// @param *arg valeur de la variable
+void
+OConfig::parse(const char *var, const char *arg)
+{
+ if (!arg) throw "OConfig::parse : Error during config file parsing";
+ std::string varName (var);
+ if (varName == "Cam_color")
+ {
+ std::string argName (arg);
+ if (argName == "RGB") inputColor = Image::rgb;
+ else if (argName == "BGR") inputColor = Image::bgr;
+ else if (argName == "YUV") inputColor = Image::yuv;
+ else if (argName == "HSI") inputColor = Image::hsi;
+ return;
+ }
+ // Affecte la valeur de arg a la variable varName
+ if (varName == "NN_step_learning") nnSl = atof(arg);
+ else if (varName == "NN_neighborhood_learning") nnNl = atof(arg);
+ else if (varName == "NN_number_of_iteration_learning") nnNil = atol(arg);
+ else if (varName == "NN_number_of_color_to_segment") nnNbColor = atoi(arg);
+ else if (varName == "NN_threshold_output") nnThresholdOutput = atoi(arg);
+ else if (varName == "NN_lum_inosity_influence") nnInfluLum = atof(arg);
+ else if (varName == "UI_img_path ") strcpy(imgPath, arg);
+ else if (varName == "NN_lazy_threshold") nnLazyThreshold = atoi(arg);
+// else if (varName == "Map_error") mapError = atoi(arg);
+// else if (varName == "Map_error_part") mapErrorPart = atoi(arg);
+// else if (varName == "Map_angle_ball_weight") angleBallWeight= atoi(arg);
+// else if (varName == "Map_distance_ball_robot_weight") distanceBallRobotWeight = atoi(arg);
+// else if (varName == "Map_distance_ball_goal_weight") distanceBallGoalWeight = atoi(arg);
+// else if (varName == "Map_ball_density_weight") ballDensityWeight = atoi(arg);
+// else if (varName == "Map_ennemy_presence_weight") ennemyPresenceWeight = atoi(arg);
+// else if (varName == "Map_ball_precision_weight") ballPrecisionWeight = atoi(arg);
+// else if (varName == "Map_skepticism_weight") skepticismWeight = atoi(arg);
+// else if (varName == "Map_skepticism_max") skepticismMax = atoi(arg);
+// else if (varName == "Map_ball_lost_weight") ballLostWeight = atoi(arg);
+// else if (varName == "Map_ball_bottom_time_out") ballBottomTimeOut = atoi(arg);
+ else if (varName == "Group_minimum_length_zone") minLengthZone = atoi(arg);
+ else if (varName == "Group_jump_point_distance") jumpPointDist = atoi(arg);
+ else if (varName == "UI_group_to_display") uiGroupToDisplay = atoi(arg);
+}
+
+/// Charge les variables du fichier de configuration (par défaut rc/vision.conf)
+void
+OConfig::load (const char *filename)
+{
+ const int NBARG = 3;
+ char *cut[NBARG] = {0};
+ FILE *file;
+ char ligne[50];
+ int i;
+ // Ouverture du fichier de conf
+ file = fopen(filename, "r");
+ if (!file) throw "OConfig::OConfig : Error during config file opening";
+ else std::cout << "Lecture du ficher de configuration" << std::endl;
+ // Parcours des lignes et analyse
+ while(fgets(ligne, 50, file))
+ {
+ if (ligne[0] == '#') continue;
+ // Division du string
+ cut[0] = strtok(ligne, " \n");
+ if (!cut[0]) continue;
+ i=0;
+ while ((cut[i] != 0) && (i<(NBARG-1)))
+ {
+ i++;
+ cut[i] = strtok( 0, " \t\n");
+ }
+ parse(cut[0], cut[2]);
+ }
+}
+
+/// Chargement des poids d'un reseau de neurones
+/// @param *filePath nom du fichier de poids a charger
+void
+OConfig::loadNNFile (const char *filePath)
+{
+ const int maxChar = 50;
+ // Ouverture du fichier de conf
+ std::ifstream file (filePath);
+ if (!file)
+ {
+ throw "OConfig::LoadNNFile : Error during poids file opening";
+ return;
+ }
+ // Chargement des couleurs
+ char buf [maxChar];
+ while (!file.eof ())
+ {
+ file.getline (buf, maxChar);
+ std::string line (buf);
+ if (line.find("#index") != std::string::npos)
+ break;
+ if (buf[0] == '\0' || buf[0] == ' ' || buf[0] == '\n'
+ || buf[0] == '\t' || buf[0] == '#') continue;
+ std::istringstream iss (buf);
+ ObjectColor tmp;
+ iss >> tmp.label >> tmp.color;
+ groupColor.push_back (tmp);
+ }
+ // Chargement des poids
+ std::vector<int> tmpNode, tmpIndex;
+ int tmp;
+ while (!file.eof ())
+ {
+ file.getline (buf, maxChar);
+ std::istringstream iss (buf);
+ if (buf[0] == '\0' || buf[0] == ' ' || buf[0] == '\n'
+ || buf[0] == '\t' || buf[0] == '#') continue;
+ iss >> tmp;
+ tmpIndex.push_back (tmp);
+ for (int i=0; i<3; i++)
+ {
+ iss >> tmp;
+ tmpNode.push_back (tmp);
+ }
+ }
+ file.close ();
+ // Recopie dans des tableaux
+ delete [] node;
+ node = new unsigned char[tmpNode.size ()];
+ for (unsigned int i=0; i<tmpNode.size (); ++i)
+ node[i] = (unsigned char)tmpNode[i];
+ delete [] index;
+ index = new int[tmpIndex.size ()];
+ for (unsigned int i=0; i<tmpIndex.size (); ++i)
+ index[i] = (unsigned char)tmpIndex[i];
+ nnNbNodeMax = tmpIndex.size ();
+}
+
+/// Creation d'un fichier de poids pour le reseau de neurones
+/// @param *filename nom du fichier a creer
+/// @param mode mode de l'espace de couleur
+/// @param nbOutput_ nombre de couleurs a detecter du reseau de neurones
+void
+OConfig::createNNFile (const char *filename, const int nbOutput_) const
+{
+ if (!node)
+ {
+ throw "OConfig::CreateNNFile : NN non initialisé";
+ return;
+ }
+ // Ecriture dans un fichier
+ std::ofstream file (filename);
+ // Couleurs
+ for (std::vector<ObjectColor>::const_iterator i = groupColor.begin (); i < groupColor.end (); ++i)
+ file << i->label << " " << i->color << "\n";
+ // Poids
+ file << "#index\t#x1\tx2\tx3\n";
+ for (int i=0; i<nbOutput_; i++)
+ {
+ file << index[i] << "\t";
+ for (int j=0; j<3; j++)
+ file << node[i*3+j] << "\t";
+ file << "\n";
+ }
+ file.close ();
+}
+
+/// Chargement de la liste des points pour les distances
+void
+OConfig::loadDistFile (const char *filename)
+{
+ // Ouverture du fichier de distance
+ std::ifstream file (filename);
+ if (!file) {
+ throw "OConfig::LoadDistFile : Error during poids file opening";
+ return;
+ }
+ // Parcours des lignes et analyse
+ char buf[50];
+ int point[4];
+ while (!file.eof () && file.getline (buf, 50))
+ if ((buf[0] >= '0') && (buf[0] <= '9'))
+ {
+ sscanf(buf, "%i\t%i\t%i\t%i\n", &point[0], &point[1], &point[2], &point[3]);
+ spaceTabPoint.push_back(point[0]);
+ spaceTabPoint.push_back(point[1]);
+ spaceTabPoint.push_back(point[2]);
+ spaceTabPoint.push_back(point[3]);
+ }
+ file.close ();
+ // Nombre de points venant d'être chargés
+ spaceNbDistPoint = spaceTabPoint.size () / 4;
+}
+
+/// Creation d'un fichier pour la liste des points pour les distances
+void
+OConfig::createDistFile (const char *filename, const int numPoint) const
+{
+ if (spaceTabPoint.size () == 0)
+ {
+ throw "OConfig::CreateDistFile : spaceTabPoint vide";
+ return;
+ }
+ // Ecriture dans un fichier
+ std::ofstream file (filename);
+ // Remplissage du fichier
+ file << "#imgX\timgY\tdistX\tdistY\n";
+ for (int i=0; i<numPoint; i++)
+ file << spaceTabPoint[i*4+0] << "\t" << spaceTabPoint[i*4+1] << "\t"
+ << spaceTabPoint[i*4+2] << "\t" << spaceTabPoint[i*4+3] << "\n";
+ file.close ();
+}
+
diff --git a/2005/i/robert/src/ovision/see/oconfig.hh b/2005/i/robert/src/ovision/see/oconfig.hh
new file mode 100644
index 0000000..890a12e
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/oconfig.hh
@@ -0,0 +1,138 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef config_h
+#define config_h
+
+#include <vector>
+#include <string>
+#include "image/image.hh"
+
+struct ObjectColor
+{
+ std::string label;
+ int color;
+};
+
+
+/// Charge le fichier config et distribue les variables
+class OConfig
+{
+ static OConfig* instance;
+ /// Parse une ligne du fichier de config
+ void parse (const char *var, const char *arg);
+
+ public:
+ /// Constructeur
+ OConfig (const char *filename = "rc/vision.conf");
+ /// Destructeur
+ ~OConfig (void);
+
+ /////////////////////////////// RESEAU DE NEURONES ///////////////////////////////////////////////////
+ /// nombre d'iteration pour l'apprentissage(number iteration learning)
+ unsigned long nnNil;
+ /// vitesse d'apprentissage (step learning)
+ double nnSl;
+ /// influence sur les voisins pour l'apprentissage (neighborhood learning)
+ double nnNl;
+ /// seuil pour la verification des noeuds de sorties inutiles du reseau
+ int nnLazyThreshold;
+ /// nombre de couleurs a detecter
+ int nnNbColor;
+ /// nombre de couleurs dans le fichier des seuils
+ int nnNbColorMax;
+ /// nombre de couleurs dans le fichier des poids
+ int nnNbNodeMax;
+ /// influence de la luminosite dans l'integration de l'image
+ double nnInfluLum;
+ /// seuil de couleur indéfini si la sortie du réseau n'est pas assez grande
+ int nnThresholdOutput;
+ /// tableau des poids du reseau de neurones
+ unsigned char *node;
+ ////////////////////////////////// MAP ///////////////////////////////////////////////////////////////
+ /// erreur accepte pour la construction de la map
+ int mapError;
+ int mapErrorPart;
+ /// Position de la balle (devant, derriere, cote, ...)
+ int angle_ball_weight;
+ /// Distance Balle-Robot
+ int distance_ball_robot_weight;
+ /// Distance Balle_goal
+ int distance_ball_goal_weight;
+ /// Densite de balles dans la zone
+ int ball_density_weight;
+ /// Presence du robot adverse dans la zone
+ int ennemy_presence_weight;
+ /// Precision de la position de la balle
+ int ball_precision_weight;
+ /// Viabilite de l'information
+ int skepticism_weight;
+ /// Max de la valeur
+ int skepticism_max;
+ /// Décrémentation lorsqu'une balle est perdue
+ int ball_lost_weight;
+ /// temps avant que le marqueur de la balle commence a descendre si elle est partie vers le bas
+ int ball_bottom_time_out;
+ /////////////////////////////// GROUP ////////////////////////////////////////////////////////////////
+ /// liste des objects à rechercher
+ std::vector<ObjectColor> groupColor;
+ /// distance des sauts pour la recherche des balles
+ int jumpPointDist;
+ /// tableau de correspondances des couleurs RGB
+ unsigned char *color;
+ /////////////////////////////// MAGNIFIER ////////////////////////////////////////////////////////////////
+ /// taille minimum des zones trouvées
+ int minLengthZone;
+ /////////////////////////////// SPACE ////////////////////////////////////////////////////////////////
+ /// Points utilises pour le calcul de distance
+ // Liste des points chargés
+ std::vector<int> spaceTabPoint;
+ // Nombre de points chargés
+ int spaceNbDistPoint;
+ //float one_nn_learning_rate;
+ //int one_nn_learning_iteration;
+ /////////////////////////////// UI ////////////////////////////////////////////////////////////////
+ /// tableau d'index des couleurs a melanger (merge)
+ int *index;
+ /// Chemin d'acces des images
+ char imgPath[30];
+ /// Objet à afficher sur l'interface
+ int uiGroupToDisplay;
+ /// Mode de couleurs des images chargées
+ Image::PixelFormat inputColor;
+
+ /// Chargement de poids pour le reseau de neurone
+ void loadNNFile (const char *filePath = "rc/poids");
+ /// Creation d'un fichier de poids pour le reseau de neurones
+ void createNNFile (const char *file, int nbOutput) const;
+ /// Creatio du fichier de la table de distance
+ void createDistFile (const char *filename, int numPoint) const;
+ /// Chargement du fichier de la table de distance
+ void loadDistFile (const char *filename);
+ static OConfig* getInstance () {return instance;}
+ /// Charge les fichiers de conf
+ void load (const char *filename = "rc/vision.conf");
+};
+
+
+#endif // config_h
diff --git a/2005/i/robert/src/ovision/see/segm.cc b/2005/i/robert/src/ovision/see/segm.cc
new file mode 100644
index 0000000..f194ce2
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/segm.cc
@@ -0,0 +1,84 @@
+// segm.cc - Classe Segmentation
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file segm.cc Segmente l'image et cree un tableau contenant des valeurs segmentees, creation du reseau de neurones
+#include "segm.hh"
+#include <iostream>
+#include <stdlib.h>
+
+/// Constructor Segm
+Segm::Segm ()
+ : index_ (0), node_ (0), lumPos_ (-1)
+{
+ oconfig_= OConfig::getInstance ();
+ nbOutput_= oconfig_->nnNbColor;
+}
+
+/// Destructor Segm
+Segm::~Segm ()
+{
+ delete [] node_;
+ delete [] index_;
+}
+
+/// Affiche les poids du reseau de neurones (neural network : NN)
+void
+Segm::showNodes () const
+{
+ // Affichage des poids du NN
+ std::cout << "Poids:\n";
+ for(int i=0; i<nbOutput_; i++)
+ std::cout << "\t" << (int)node_[i*3] << " "
+ << (int)node_[i*3+1] << " " << (int)node_[i*3+2] << "\n";
+ std::cout << std::endl;
+}
+
+/// Segmente l'image avec le reseau de neurones
+void
+Segm::segmImg (Img *img)
+{
+ // Initialisation
+ unsigned char* d = img->tabData_;
+ delete [] img->tabSegm_;
+ img->tabSegm_= new unsigned char[img->nbPixels_];
+ unsigned char *s = img->tabSegm_;
+ // Parcours de l'image pour la segmentation
+ // On recupere l'indextabSegm_et non le numero de sortie du NN
+ for (unsigned long i=0; i<img->nbPixels_; i++)
+ {
+ *(s++) = index_[giveColor (d)];
+ d += 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
+Segm::segmImg (Img *img, const int numColor)
+{
+ unsigned char* d = img->tabData_;
+ delete [] img->tabSegm_;
+ img->tabSegm_= new unsigned char[img->nbPixels_];
+ unsigned char *s = img->tabSegm_;
+ // Parcours de l'image pour la segmentation
+ for (unsigned long i=0; i<img->nbPixels_; i++)
+ {
+ numColor == index_[giveColor (d)] ? *s = 1 : *s = 0;
+ ++s;
+ d += 3;
+ }
+}
+
+/// Configure le mode de couleur utilisé
+void
+Segm::setMode (const Image::PixelFormat color)
+{
+ switch (color)
+ {
+ case Image::rgb: lumPos_= -1; break;
+ case Image::yuv: lumPos_= 0; break;
+ case Image::hsi: lumPos_= 2; break;
+ default: lumPos_= -1;
+ }
+}
diff --git a/2005/i/robert/src/ovision/see/segm.hh b/2005/i/robert/src/ovision/see/segm.hh
new file mode 100644
index 0000000..290ecf1
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/segm.hh
@@ -0,0 +1,80 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef segm_h
+#define segm_h
+
+#include "img.hh"
+#include "oconfig.hh"
+#include "image/image.hh"
+
+/// Segmente l'image et cree un tableau contenant des valeurs segmentees, creation du reseau de neurones et apprentissage
+class Segm
+{
+ friend class Comm;
+
+ public:
+ /// Constructeur
+ Segm ();
+ /// Destructeur
+ virtual ~Segm ();
+ /// Affiche la valeur des poids du NN
+ void showNodes () const;
+ /// Donne la couleur à partir du tableau
+ virtual unsigned char giveColor (const unsigned char *x, const bool testOutputMax = false, const bool indexProcess = false) = 0;
+ /// Segmentation de l'image
+ void segmImg (Img *img);
+ /// Segmentation de l'image permettant d'isoler une couleur
+ void segmImg (Img *img, const int numColor);
+ /// reset la luminosité
+ void clearLum () {lum_ = 0; nbLumData_ = 0;}
+ /// Renvoie la luminosité
+ unsigned long getLum () const {return nbLumData_?lum_/nbLumData_:0;}
+ /// Configure le mode de couleur utilisé
+ void setMode (const Image::PixelFormat color);
+ // Constantes
+ static const bool min = 0;
+ static const bool max = 1;
+ static const int undefined = 254;
+ /// Constantes pour la creation du NN
+ enum initModes {generate, loadFromFile};
+
+ protected:
+ /// Classe config
+ OConfig *oconfig_;
+ /// nb de couleurs a differencier
+ int nbOutput_;
+ /// index des couleurs pour melanger (merge) les couleurs
+ int *index_;
+ /// tableau de poids du NN
+ unsigned char *node_;
+ /// Position de la composante de luminosité
+ int lumPos_;
+ /// Sauvegarde de la luminosité
+ unsigned long lum_;
+ /// Sauvegarde du nombre de données sauvegardées concernant la luminosité
+ int nbLumData_;
+ /// Ajout de la luminosité
+ void addLum (int lumToAdd) {lum_ += lumToAdd; ++nbLumData_;}
+};
+
+#endif // segm_h
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);
+}
+
diff --git a/2005/i/robert/src/ovision/see/segmLearn.hh b/2005/i/robert/src/ovision/see/segmLearn.hh
new file mode 100644
index 0000000..3d0f564
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/segmLearn.hh
@@ -0,0 +1,53 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef segmLearn_h
+#define segmLearn_h
+
+#include "segm.hh"
+
+/// Segmente l'image avec le réseau de neurones
+class SegmLearn : public Segm
+{
+ /// memorise la popularité des noeuds pour enlever les sorties inefficaces
+ int *freq_;
+
+ public:
+ /// Constructeur
+ SegmLearn ();
+ /// Destructeur
+ virtual ~SegmLearn (void);
+ /// Apprentissage du NN
+ void trainNN (Img *img);
+ /// Cree le NN
+ void buildNN (const int nbOutput, const bool loadFromFile = false);
+ /// Renvoie le code la couleur segmentee
+ virtual unsigned char giveColor (const unsigned char *x, const bool testUndefined = false, const bool indexProcess = false);
+
+ private:
+ /// Genere des poids pour un noeud
+ void weightsGen (const int numNode);
+ /// Renvoie le code de la couleur segmentee
+ unsigned char findColorNN (const unsigned char *x, const bool testOutputMax = false) const;
+};
+
+#endif // segmLearn_h
diff --git a/2005/i/robert/src/ovision/see/segmTable.cc b/2005/i/robert/src/ovision/see/segmTable.cc
new file mode 100644
index 0000000..9f76726
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/segmTable.cc
@@ -0,0 +1,30 @@
+// segmTable.cc - Classe Segmentation
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file segmTable.cc Segmente l'image et cree un tableau contenant des valeurs segmentees, creation du reseau de neurones
+#include "segmTable.hh"
+#include "convertImg.hh"
+#include <fstream>
+#include <iostream>
+
+/// Constructor SegmTable
+
+/// @param img classe img permettant d'acceder au donnees de l'image a traiter
+/// @param oconfig_ classe oconfig_ permettant d'acceder aux variables de oconfig_uration
+SegmTable::SegmTable (ColorTable &tab)
+ : tab_ (tab)
+{
+}
+
+/// Donne la couleur à partir du tableau
+/// @param *x pointeur vers un tableau contenant une valeur RGB
+unsigned char
+SegmTable::giveColor (const unsigned char *x, const bool testOutputMax, const bool index_Process)
+{
+ if (lumPos_ >= 0) addLum (x[lumPos_]);
+// if (index_Process)
+ return index_ [tab_[(int) (x[0] * ColorTable::colorTabSize2 + x[1] * ColorTable::colorTabSize + x[2]) ]];
+// else
+// return colorTable_[ x[0]*colorTabSize2 + x[1]*colorTabSize + x[2] ];
+}
diff --git a/2005/i/robert/src/ovision/see/segmTable.hh b/2005/i/robert/src/ovision/see/segmTable.hh
new file mode 100644
index 0000000..4051a43
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/segmTable.hh
@@ -0,0 +1,41 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef segmTable_h
+#define segmTable_h
+
+#include "segm.hh"
+#include "colorTable.hh"
+
+/// Segmente l'image sans le réseau de neurones pour de meilleures performances
+class SegmTable : public Segm
+{
+ /// Tableau de correspondance couleurs pixels -> couleur donnée par le rezo
+ ColorTable &tab_;
+ public:
+ /// Constructeur
+ SegmTable (ColorTable &tab);
+ /// Donne la couleur à partir du tableau
+ virtual unsigned char giveColor (const unsigned char *x, const bool testOutputMax = false, const bool indexProcess = false);
+};
+
+#endif // segmTable_h
diff --git a/2005/i/robert/src/ovision/see/space.cc b/2005/i/robert/src/ovision/see/space.cc
new file mode 100644
index 0000000..c77a6b2
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/space.cc
@@ -0,0 +1,189 @@
+// space.cc - Classe Space
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file space.cc Etalonnage des distances et localisation de la balle
+
+#include "space.hh"
+
+#include "group.hh"
+#include "stdio.hh"
+
+using namespace std;
+
+/// Constructeur
+/// @param imgHeight hauteur de l'image
+/// @param imgWidth largeur de l'image
+Space::Space (int imgWidth, int imgHeight)
+{
+ Space::imgHeight = imgHeight;
+ Space::imgWidth = imgWidth;
+
+ Space::oconfig = OConfig::GetInstance ();
+
+ tabY = NULL;
+ tabX = NULL;
+}
+
+
+/// Destructeur
+Space::~Space ()
+{
+}
+
+
+/// Cree un fichier gnuplot avec la courbe des points donnés par la courbe x et y
+void
+Space::CreateGnuPlotFile (int y)
+{
+ FILE *file;
+ double locY, locX;
+
+ // Ouverture du fichier
+ file = fopen("dataY", "w+");
+
+ // Parcours pour tous les pixels verticaux de l'image
+ for (int i=0; i<296; i++)
+ {
+ GetLoc(0, i, locX, locY);
+ fprintf(file, "%i\t%f\n", i, locY);
+ }
+ // Fermeture du fichier
+ fclose(file);
+
+ // Ouverture du fichier
+ file = fopen("dataX", "w+");
+
+ // Parcours de tous les pixels horizontaux
+ for (int i=0; i<352; i++)
+ {
+ GetLoc(0, y, locX, locY);
+ fprintf(file, "%i\t%f\n", i, locX);
+ }
+ // Fermeture du fichier
+ fclose(file);
+
+}
+
+
+/// Ajoute un point pour l'etalonnage
+void
+Space::AddSetupPoint(int x, int y, int distx, int disty)
+{
+ SETUP_POINT setupPoint;
+
+ setupPoint.x = x;
+ setupPoint.y = y;
+ setupPoint.distx = distx;
+ setupPoint.disty = disty;
+
+ setupTab.push_back(setupPoint);
+}
+
+
+/// Chargement des points a partir d'un fichier
+void
+Space::LoadFromFile()
+{
+ // Parcours de tous les points du fichier dist
+ for (int i=0; i<oconfig->nbDistPoint; i++)
+ AddSetupPoint(oconfig->tabPoint[i*4+0], oconfig->tabPoint[i*4+1], oconfig->tabPoint[i*4+2], oconfig->tabPoint[i*4+3]);
+
+ cout << "Nombre de points loadé pour le calibrage de la distance: " << setupTab.size () << endl;
+}
+
+
+/// Donne les coefficients d'une ligne
+void
+Space::FindCoeffLine (double x1, double y1, double x2, double y2, double &a, double &b)
+{
+ a = (x2 - x1) / (y2 - y1);
+ b = x1 - a * y1;
+}
+
+
+/// Etalonnage des distances
+int
+Space::Setup(double a, double b, double c)
+{
+ // Assignation des coefficients pour le calcul des y
+ aY = a;
+ bY = b;
+ cY = c;
+
+ double a1, b1, a2, b2;
+
+ // Cherche les coordonnées de 2 droites
+ FindCoeffLine (65, 9, 118, 180, a1, b1);
+ FindCoeffLine (198, 10, 192, 180, a2, b2);
+
+ // Allocation de la mémoire
+ delete []tabY;
+ tabY = new double[imgHeight];
+
+ delete []tabX;
+ tabX = new double[imgHeight*imgWidth];
+
+ // Création du tableau de correspondance pour les x
+ double diffPix;
+ double unitPix;
+ double center;
+ for (int y=0; y<imgHeight; y++)
+ {
+ // Calcul de la "longeur réelle" d'un pixel
+ diffPix = (a2*y+b2) - (a1*y+b1);
+ unitPix = 100.0f / diffPix;
+ tabY[y] = unitPix;
+
+ // Calcul du centre du robot sur l'image en fonction du y
+ center = a2*y + b2;
+// cout << y << "\t" << tabY[y] << endl;
+
+ // Parcours de tous les x de la ligne et calcul de la distance correspondante
+ for (int x=0; x<imgWidth; x++)
+ tabX[y*imgWidth + x] = unitPix *(x - center);
+ }
+
+ return 1;
+}
+
+
+/// Position d'un objet dans le referentiel du robot
+void
+Space::GetLoc(int locImgX, int locImgY, double &locX, double &locY)
+{
+ // Calcul de locX
+ locX = tabX[locImgY*imgWidth + locImgX];
+
+ // Calcul de locY
+ locY = aY*locImgY*locImgY + bY*locImgY + cY;
+}
+
+
+
+/// Position d'un objet dans le referentiel du robot
+void
+Space::GetLoc(int locImgX, int locImgY, int &locX, int &locY)
+{
+ double x,y;
+ GetLoc(locImgX, locImgY, x, y);
+ locX = (int)x;
+ locY = (int)y;
+}
+
+
+/// Donne la position reelle sur la table de la balle
+/// @param locX, locY : position de la balle dans le rÃfÃrentiel du robot
+/// @param posRobotX, posRobotY, angleRobot : position du robot sur la table
+/// @param posX, posY : variable de retour pour la position de la balle sur la table
+void
+Space::GetPos(double locX, double locY, double posRobotX, double posRobotY, double angleRobot, double &posX, double &posY)
+{
+ double sinus = sin(angleRobot);
+ double cosinus = cos(angleRobot);
+
+ // Calcul des coordonnes avec le changement de repere
+ posX = posRobotX + locX*cosinus - locY*sinus;
+ posY = posRobotY + locX*sinus + locY*cosinus;
+}
+
diff --git a/2005/i/robert/src/ovision/see/space.hh b/2005/i/robert/src/ovision/see/space.hh
new file mode 100644
index 0000000..0a3b224
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/space.hh
@@ -0,0 +1,104 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef space_h
+#define space_h
+
+#include <vector>
+#include <iostream>
+#include <stdio.h>
+
+#include "group.hh"
+#include "oconfig.hh"
+
+//#define NB_NODES_X 5
+//#define NB_NODES_Y 3
+
+//#define START_WEIGHT_MIN 0.1
+//#define START_WEIGHT_MAX 0.9
+
+
+struct SETUP_POINT
+{
+ int x, y;
+ int distx, disty;
+};
+
+
+/// Etalonnage des distances et localisation de la balle
+class Space
+{
+ /// Classe config
+ OConfig *oconfig;
+
+ /// tableau d'index des distances
+ double *tabX;
+ double *tabY;
+
+ /// liste des distances etalonnees
+ std::vector<SETUP_POINT> setupTab;
+
+ /// hautdddeur de l'image
+ int imgHeight;
+
+ /// largeur de l'image
+ int imgWidth;
+
+ double aY, bY, cY;
+
+ public:
+
+ // Constructeur
+ Space (int width, int height);
+
+ // Destructeur
+ ~Space ();
+
+ /// Position d'un objet dans le referentiel du robot
+ void GetLoc(int locImgX, int locImgY, int &locX, int &locY);
+ void GetLoc(int locImgX, int locImgY, double &locX, double &locY);
+
+ /// Donne la position reelle sur la table de la balle
+ void GetPos(double locX, double locY, double posRobotX, double posRobotY, double angleRobot, double &posX, double &posY);
+
+ /// Ajoute un point pour l'etalonnage
+ void AddSetupPoint(int x, int y, int distx, int disty);
+
+ /// Chargement des points a partir d'un fichier
+ void LoadFromFile();
+
+ /// Etalonnage des distances
+ int Setup(double aY, double bY, double cY);
+
+ protected:
+
+ /// Donne les coefficients d'une ligne
+ void FindCoeffLine (double x1, double y1, double x2, double y2, double &a, double &b);
+
+ /// Cree un fichier gnuplot avec la courbe des points donnés par la courbe x et y
+ void CreateGnuPlotFile (int y = 100);
+
+ /// Cree un fichier avec l'erreur en fonction des itérations
+ void LogErrorPoint (FILE *f, int iter);
+};
+
+#endif // space_h
diff --git a/2005/i/robert/src/ovision/see/test_cam.cc b/2005/i/robert/src/ovision/see/test_cam.cc
new file mode 100644
index 0000000..193d8d2
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/test_cam.cc
@@ -0,0 +1,36 @@
+// test_cam.cc
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+#include <iostream>
+
+#include "oconfig.hh"
+#include "group.hh"
+
+#include "video4linux/video4linux.hh"
+#include "utils/errno_exception.hh"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <stdexcept>
+#include <string>
+int main(int argc, char **argv)
+{
+ // Initialisation des classes
+ Img img;
+ OConfig config("rc/vision.conf");
+ // Acquisition de l'image et sauvegarde
+ if (argv[1]) ;
+ else
+ {
+ Image::PixelFormat pf = Image::yuv;
+ Video4Linux vid ("/dev/video", pf);
+ vid.calibrate ();
+ img.load (vid);
+ }
+ img.writeRaw ("shots/toto.yuv");
+}
+
diff --git a/2005/i/robert/src/ovision/see/test_colortable.cc b/2005/i/robert/src/ovision/see/test_colortable.cc
new file mode 100644
index 0000000..b803093
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/test_colortable.cc
@@ -0,0 +1,49 @@
+// test_group.cc
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "segmLearn.hh"
+#include "segmTable.hh"
+#include "colorTable.hh"
+#include "oconfig.hh"
+#include "imgInterface.hh"
+
+int
+main(int argc, char **argv)
+{
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Usage
+ if (argc < 2)
+ {
+ std::cout << "Usage : test_colortable <filename>" << std::endl;
+ return 1;
+ }
+ /////////////////////////////////////////////////////////////////////////////////////////
+ /// Initialisation des classes
+ OConfig *oconfig_;
+ try
+ {
+ oconfig_ = new OConfig ("rc/vision.conf");
+ }
+ catch (std::string &e)
+ {
+ std::cerr << e << std::endl;
+ return 1;
+ }
+ ImgInterface img;
+ img.loadRaw (argv[1], Image::rgb, 360, 296);
+ ColorTable tab;
+ SegmTable segm (tab);
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Création de l'image segmentée
+ segm.segmImg (&img);
+ img.doImg ();
+ img.writeRaw ("shots/segm.rgb");
+ return 0;
+}
+
+
diff --git a/2005/i/robert/src/ovision/see/test_group.cc b/2005/i/robert/src/ovision/see/test_group.cc
new file mode 100644
index 0000000..bcd4ae2
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/test_group.cc
@@ -0,0 +1,55 @@
+// test_group.cc
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "segmLearn.hh"
+#include "segmTable.hh"
+#include "colorTable.hh"
+#include "oconfig.hh"
+#include "group.hh"
+#include "imgInterface.hh"
+
+int
+main(int argc, char **argv)
+{
+ /////////////////////////////////////////////////////////////////////////////////////////
+ /// Initialisation des classes
+ OConfig *oconfig_;
+ try
+ {
+ oconfig_ = new OConfig ("rc/vision.conf");
+ }
+ catch (std::string &e)
+ {
+ std::cerr << e << std::endl;
+ return 1;
+ }
+ ImgInterface img;
+ img.loadRaw ("shots/test.rgb", Image::rgb, 360, 296);
+ SegmLearn segm;
+ segm.buildNN (oconfig_->nnNbColor, Segm::loadFromFile);
+ Group group(&img, &segm);
+ /////////////////////////////////////////////////////////////////////////////////////////
+ /// Initialise les couleurs à chercher
+ std::vector<ObjectColor> colorList;
+ ObjectColor tmp;
+ tmp.label = "ball";
+ tmp.color = 4;
+ colorList.push_back (tmp);
+ /////////////////////////////////////////////////////////////////////////////////////////
+ /// Cherche les groupes
+ group.jumpPoints(colorList);
+ group.showZones();
+ ////////////////////////////////////////////////////////////////////////////////////////
+ /// Crée une image pour afficher les groups
+ group.jumpPoints(colorList);
+ std::vector<Zone> &test = group.getZoneList ();
+ img.doGroupImg (test);
+ img.doImg (img.getTabSegm ());
+ img.writeRaw ("shots/group.rgb", img.getTabOut ());
+}
+
diff --git a/2005/i/robert/src/ovision/see/test_img.cc b/2005/i/robert/src/ovision/see/test_img.cc
new file mode 100644
index 0000000..065db70
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/test_img.cc
@@ -0,0 +1,22 @@
+// test_img.cc
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+#include "oconfig.hh"
+#include "video4linux/video4linux.hh"
+#include "image/image.hh"
+#include <iostream>
+#include "imgInterface.hh"
+
+
+int main(int argc, char **argv)
+{
+ ImgInterface img;
+ OConfig config("rc/vision.conf");
+ // Chargement de l'image
+ img.loadRaw (argv[1], Image::rgb, 360, 296);
+ // Inversion de l'image
+ img.mirror ();
+ img.writeRaw ("shots/toto.rgb");
+}
+
diff --git a/2005/i/robert/src/ovision/see/test_magnifier.cc b/2005/i/robert/src/ovision/see/test_magnifier.cc
new file mode 100644
index 0000000..bee1398
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/test_magnifier.cc
@@ -0,0 +1,55 @@
+// test_group.cc
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "segmLearn.hh"
+#include "segmTable.hh"
+#include "colorTable.hh"
+#include "oconfig.hh"
+#include "group.hh"
+#include "imgInterface.hh"
+#include "magnifier.hh"
+
+int
+main(int argc, char **argv)
+{
+ /////////////////////////////////////////////////////////////////////////////////////////
+ /// Initialisation des classes
+ OConfig *oconfig_;
+ try
+ {
+ oconfig_ = new OConfig ("rc/vision.conf");
+ }
+ catch (std::string &e)
+ {
+ std::cerr << e << std::endl;
+ return 1;
+ }
+ Img img;
+ img.loadRaw ("shots/test.rgb", Image::rgb, 360, 296);
+ SegmLearn segm;
+ segm.buildNN (oconfig_->nnNbColor, Segm::loadFromFile);
+ Group group (&img, &segm);
+ Magnifier mag (&img, &segm);
+ /////////////////////////////////////////////////////////////////////////////////////////
+ /// Initialise les couleurs à chercher
+ std::vector<ObjectColor> colorList;
+ ObjectColor tmp;
+ tmp.label = "ball";
+ tmp.color = 4;
+ colorList.push_back (tmp);
+ /////////////////////////////////////////////////////////////////////////////////////////
+ /// Cherche les groupes
+ group.jumpPoints (colorList);
+ group.showZones ();
+ ////////////////////////////////////////////////////////////////////////////////////////
+ /// Analyse et tri la liste de zones trouvées
+ mag.analyse (group.getZoneList ());
+ mag.showItems (Group::redSkittle);
+}
+
+
diff --git a/2005/i/robert/src/ovision/see/test_segm.cc b/2005/i/robert/src/ovision/see/test_segm.cc
new file mode 100644
index 0000000..3321852
--- /dev/null
+++ b/2005/i/robert/src/ovision/see/test_segm.cc
@@ -0,0 +1,32 @@
+// test_segm.cc - Test la segmentation
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+#include <iostream>
+
+#include "imgInterface.hh"
+#include "segmLearn.hh"
+#include "oconfig.hh"
+
+
+int main(int argc, char **argv)
+{
+ // Usage
+ if (argc < 2)
+ {
+ std::cout << "Usage : test_segm <filename>" << std::endl;
+ return 1;
+ }
+ // Initialisation des classes
+ OConfig oconfig_;
+ ImgInterface img;
+ img.loadRaw (argv[1], Image::rgb, 360, 296);
+ SegmLearn segm;
+ segm.buildNN (oconfig_.nnNbColor, Segm::loadFromFile);
+ segm.showNodes ();
+ segm.segmImg (&img);
+
+ // Création de l'image segmentée
+ img.doImg ();
+ img.writeRaw ("shots/segm.rgb", img.getTabOut ());
+}
+