From 97b69507c877a4644c0caac4f61e052e188f9d8e Mon Sep 17 00:00:00 2001 From: gaillaro Date: Tue, 5 Apr 2005 18:26:18 +0000 Subject: 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 --- 2005/i/robert/src/ovision/see/Makefile.defs | 32 +++ 2005/i/robert/src/ovision/see/colorTable.cc | 88 ++++++++ 2005/i/robert/src/ovision/see/colorTable.hh | 55 +++++ 2005/i/robert/src/ovision/see/convertImg.cc | 98 +++++++++ 2005/i/robert/src/ovision/see/convertImg.hh | 44 ++++ 2005/i/robert/src/ovision/see/group.cc | 140 ++++++++++++ 2005/i/robert/src/ovision/see/group.hh | 83 +++++++ 2005/i/robert/src/ovision/see/img.cc | 99 +++++++++ 2005/i/robert/src/ovision/see/img.hh | 73 ++++++ 2005/i/robert/src/ovision/see/imgInterface.cc | 160 ++++++++++++++ 2005/i/robert/src/ovision/see/imgInterface.hh | 59 +++++ 2005/i/robert/src/ovision/see/magnifier.cc | 167 ++++++++++++++ 2005/i/robert/src/ovision/see/magnifier.hh | 71 ++++++ 2005/i/robert/src/ovision/see/map.cc | 269 +++++++++++++++++++++++ 2005/i/robert/src/ovision/see/map.hh | 163 ++++++++++++++ 2005/i/robert/src/ovision/see/oconfig.cc | 238 ++++++++++++++++++++ 2005/i/robert/src/ovision/see/oconfig.hh | 138 ++++++++++++ 2005/i/robert/src/ovision/see/segm.cc | 84 +++++++ 2005/i/robert/src/ovision/see/segm.hh | 80 +++++++ 2005/i/robert/src/ovision/see/segmLearn.cc | 176 +++++++++++++++ 2005/i/robert/src/ovision/see/segmLearn.hh | 53 +++++ 2005/i/robert/src/ovision/see/segmTable.cc | 30 +++ 2005/i/robert/src/ovision/see/segmTable.hh | 41 ++++ 2005/i/robert/src/ovision/see/space.cc | 189 ++++++++++++++++ 2005/i/robert/src/ovision/see/space.hh | 104 +++++++++ 2005/i/robert/src/ovision/see/test_cam.cc | 36 +++ 2005/i/robert/src/ovision/see/test_colortable.cc | 49 +++++ 2005/i/robert/src/ovision/see/test_group.cc | 55 +++++ 2005/i/robert/src/ovision/see/test_img.cc | 22 ++ 2005/i/robert/src/ovision/see/test_magnifier.cc | 55 +++++ 2005/i/robert/src/ovision/see/test_segm.cc | 32 +++ 31 files changed, 2983 insertions(+) create mode 100644 2005/i/robert/src/ovision/see/Makefile.defs create mode 100644 2005/i/robert/src/ovision/see/colorTable.cc create mode 100644 2005/i/robert/src/ovision/see/colorTable.hh create mode 100644 2005/i/robert/src/ovision/see/convertImg.cc create mode 100644 2005/i/robert/src/ovision/see/convertImg.hh create mode 100644 2005/i/robert/src/ovision/see/group.cc create mode 100644 2005/i/robert/src/ovision/see/group.hh create mode 100644 2005/i/robert/src/ovision/see/img.cc create mode 100644 2005/i/robert/src/ovision/see/img.hh create mode 100644 2005/i/robert/src/ovision/see/imgInterface.cc create mode 100644 2005/i/robert/src/ovision/see/imgInterface.hh create mode 100644 2005/i/robert/src/ovision/see/magnifier.cc create mode 100644 2005/i/robert/src/ovision/see/magnifier.hh create mode 100644 2005/i/robert/src/ovision/see/map.cc create mode 100644 2005/i/robert/src/ovision/see/map.hh create mode 100644 2005/i/robert/src/ovision/see/oconfig.cc create mode 100644 2005/i/robert/src/ovision/see/oconfig.hh create mode 100644 2005/i/robert/src/ovision/see/segm.cc create mode 100644 2005/i/robert/src/ovision/see/segm.hh create mode 100644 2005/i/robert/src/ovision/see/segmLearn.cc create mode 100644 2005/i/robert/src/ovision/see/segmLearn.hh create mode 100644 2005/i/robert/src/ovision/see/segmTable.cc create mode 100644 2005/i/robert/src/ovision/see/segmTable.hh create mode 100644 2005/i/robert/src/ovision/see/space.cc create mode 100644 2005/i/robert/src/ovision/see/space.hh create mode 100644 2005/i/robert/src/ovision/see/test_cam.cc create mode 100644 2005/i/robert/src/ovision/see/test_colortable.cc create mode 100644 2005/i/robert/src/ovision/see/test_group.cc create mode 100644 2005/i/robert/src/ovision/see/test_img.cc create mode 100644 2005/i/robert/src/ovision/see/test_magnifier.cc create mode 100644 2005/i/robert/src/ovision/see/test_segm.cc (limited to '2005/i') 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 +#include +#include + +#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 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 + +/// Renvoie le minimum entre 2 nombres +inline unsigned char min (unsigned char a, unsigned char b) +{ + if (a +#include +#include + +#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::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::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 list; + ObjectColor obj; + obj.label = "undefined"; + obj.color = color; + list.push_back (obj); + jumpPoints (list); +} + +void Group::jumpPoints (const std::vector &colorList) +{ + zoneList_.clear (); + segm_->clearLum (); + segm_->setMode (img_->colorMode_); + + int tmpY; + unsigned char curColor; + std::vector::const_iterator iter; + // Parcours d'une partie des pixels de l'image + for (int y=0; yheight_; y+=oconfig_->jumpPointDist) + { + tmpY = y*img_->width_; + for (int x=0; xwidth_; 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 << " 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 +#include +#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 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 &colorList); + void jumpPoints(int color); + /// Affiche les zones trouvees + void showZones() const; + /// Accessors + std::vector &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 +#include +#include + +/// 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 &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::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 +#include + +#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 &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 +#include + +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 &list) +{ + unsigned char *pTabMin, *pTabMax; + // Parcours de la liste des groupes + for (std::vector::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; xxmax; 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; xymax; 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 &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 &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::const_iterator iter = zoneList.begin (); + iter < zoneList.end (); ++iter) + // Remplissage de la zone avec une couleur + for(int i=iter->xmin; ixmax; i++) + for (int j=iter->ymin; jymax; 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 &list); + /// Mirroir l'image + void mirror (); + /// Creation du tableau de RGB pour faire une image + void doGroupImg (const std::vector &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 &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 + +#include "magnifier.hh" + +/// Constructeur +Magnifier::Magnifier (Img *img, Segm *segm) + : segm_ (segm), img_ (img) +{ + oconfig_ = OConfig::getInstance (); + itemList_ = new std::vector[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 &zoneList) +{ + // remise à zéro de toutes les listes + for (int i=0; i::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::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::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 + +#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 *itemList_; + + public: + /// Constructeur + Magnifier (Img *img, Segm *segm); + /// Destructeur + ~Magnifier (void); + /// Analyse une liste de zones + void analyse (const std::vector &zoneList); + /// Affiche les zones trouvees après analyse + void showItems (const Group::ZoneType type) const; + /// Renvoie une liste d'objet + std::vector& 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 +#include +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::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::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::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::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 +#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 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::iterator &iter); + + /// Test si une balle trouvà correspond a une balle de la map + int TestSimilarBall(ZONE *pBall , std::list::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::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::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 +#include +#include +#include +#include + +#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 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::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= '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 +#include +#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 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 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 +#include + +/// 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; itabData_; + 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; inbPixels_; 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; inbPixels_; 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 + +/// 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; inode[i]; + for (int i = 0; iindex[i]; + } + else + { + //initialition des noeuds aléatoirement + srand((unsigned)time(0)); + for(int i=0; itabData_; + delete [] freq_; + freq_ = new int[nbOutput_]; + for(int i=0; innNil; 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; jcolorMode == 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 +#include + +/// 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; inbDistPoint; 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 +#include +#include + +#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 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 + +#include "oconfig.hh" +#include "group.hh" + +#include "video4linux/video4linux.hh" +#include "utils/errno_exception.hh" + +#include +#include +#include +#include +#include +#include +#include +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 +#include +#include + +#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 " << 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 +#include +#include + +#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 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 &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 +#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 +#include +#include + +#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 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 + +#include "imgInterface.hh" +#include "segmLearn.hh" +#include "oconfig.hh" + + +int main(int argc, char **argv) +{ + // Usage + if (argc < 2) + { + std::cout << "Usage : test_segm " << 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 ()); +} + -- cgit v1.2.3