From c2a1cd33124b69bc31fefbae73268e8b012b5879 Mon Sep 17 00:00:00 2001 From: gaillaro Date: Sat, 16 Apr 2005 23:36:41 +0000 Subject: * ajout de detection de bandes reflechissantes * variables de conf de skittle dans le fichier vision.conf * qq modifs sur l'interface --- 2005/i/robert/src/ovision/see/group.cc | 2 + 2005/i/robert/src/ovision/see/group.hh | 4 +- 2005/i/robert/src/ovision/see/magnifier.cc | 7 +++- 2005/i/robert/src/ovision/see/oconfig.cc | 6 +++ 2005/i/robert/src/ovision/see/oconfig.hh | 16 ++++++- 2005/i/robert/src/ovision/see/skittle.cc | 67 ++++++++++++++++++++---------- 2005/i/robert/src/ovision/see/skittle.hh | 16 ++++++- 2005/i/robert/src/ovision/ui/live.cc | 5 ++- 2005/i/robert/src/ovision/ui/live.hh | 4 +- 9 files changed, 96 insertions(+), 31 deletions(-) (limited to '2005/i') diff --git a/2005/i/robert/src/ovision/see/group.cc b/2005/i/robert/src/ovision/see/group.cc index 8bb80b6..e18379f 100644 --- a/2005/i/robert/src/ovision/see/group.cc +++ b/2005/i/robert/src/ovision/see/group.cc @@ -40,6 +40,7 @@ Group::addZone (const int idColor, const int xmin, const int xmax, const int ymi else if (iter->label == "border") zone.id = border; else if (iter->label == "base") zone.id = base; else if (iter->label == "gap") zone.id = gap; + else if (iter->label == "reflectBand") zone.id = reflectBand; break; } zoneList_.push_back (zone); @@ -132,6 +133,7 @@ Group::translateToColorName (const int color) else if (color == Group::gap) label = "gap"; else if (color == Group::border) label = "border"; else if (color == Group::base) label = "base"; + else if (color == Group::reflectBand) label = "reflectBand"; 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 index b1a449c..6cf2db1 100644 --- a/2005/i/robert/src/ovision/see/group.hh +++ b/2005/i/robert/src/ovision/see/group.hh @@ -67,8 +67,8 @@ class Group public: /// Type d'objects à trouver - static const int nbZoneType = 5; - enum ZoneType {greenSkittle, redSkittle, border, base, gap, undefined}; + static const int nbZoneType = 6; + enum ZoneType {greenSkittle, redSkittle, border, base, gap, reflectBand, undefined}; /// Convertit le label de couleur en nombre static std::string translateToColorName (const int color); /// Constructeur diff --git a/2005/i/robert/src/ovision/see/magnifier.cc b/2005/i/robert/src/ovision/see/magnifier.cc index e34cdd6..8ae323e 100644 --- a/2005/i/robert/src/ovision/see/magnifier.cc +++ b/2005/i/robert/src/ovision/see/magnifier.cc @@ -75,6 +75,9 @@ Magnifier::analyse (const std::vector &zoneList) case Group::border: if (isBorder (*iter)) addItem (*iter); break; + case Group::reflectBand: + addItem (*iter); + break; } } if (itemList_[Group::redSkittle].size () != 0) @@ -100,7 +103,6 @@ Magnifier::checkIsUnique (const Zone &zone) 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; @@ -113,7 +115,8 @@ bool Magnifier::isSkittle (Zone &zone) { Skittle s (img_, segm_); - s.analyse (zone); + s.analyse (zone, itemList_[Group::reflectBand]); + s.show (); return true; } diff --git a/2005/i/robert/src/ovision/see/oconfig.cc b/2005/i/robert/src/ovision/see/oconfig.cc index 77785a3..41337a8 100644 --- a/2005/i/robert/src/ovision/see/oconfig.cc +++ b/2005/i/robert/src/ovision/see/oconfig.cc @@ -70,8 +70,14 @@ OConfig::parse (const char *var, const char *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); + else if (varName == "Skittle_border") skittleBorder = atoi(arg); + else if (varName == "Skittle_grow") skittleGrow = atoi(arg); + else if (varName == "Skittle_div_jump") skittleDivJump = atoi(arg); + else if (varName == "Skittle_vertical_ratio") skittleVerticalRatio = atof(arg); + else if (varName == "Skittle_score_bend_ratio") skittleScoreBendRatio = atof(arg); } + /// Charge les variables du fichier de configuration (par défaut rc/vision.conf) void OConfig::load (const char *filename) diff --git a/2005/i/robert/src/ovision/see/oconfig.hh b/2005/i/robert/src/ovision/see/oconfig.hh index 890a12e..783ff48 100644 --- a/2005/i/robert/src/ovision/see/oconfig.hh +++ b/2005/i/robert/src/ovision/see/oconfig.hh @@ -120,7 +120,21 @@ class OConfig int uiGroupToDisplay; /// Mode de couleurs des images chargées Image::PixelFormat inputColor; - + /////////////////////////////// UI //////////////////////////////////////////////////////////////// + /// Bordure de la zone utilisée pour rétrécir la quille avant l'analyse de la + /// courbure de celle-ci + int skittleBorder; + /// Elargissement de la zone de n pixels pour l'acquisition des points utilisés + /// pour le calcul de la composante principale + int skittleGrow; + /// Division de la fréquence des sauts pour la fonction pca et bend + int skittleDivJump; + /// Ratio utilisé pour déterminer si une quille est verticale + double skittleVerticalRatio; + /// Ratio utilisé pour déterminer si le résultat d'une analyse de courbure est + /// cohérent + double skittleScoreBendRatio; + /// 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 diff --git a/2005/i/robert/src/ovision/see/skittle.cc b/2005/i/robert/src/ovision/see/skittle.cc index a1b4bfd..3fb5f64 100644 --- a/2005/i/robert/src/ovision/see/skittle.cc +++ b/2005/i/robert/src/ovision/see/skittle.cc @@ -11,7 +11,7 @@ /// Constructeur Skittle::Skittle (Img *img, Segm *segm) - : segm_ (segm), img_ (img) + : segm_ (segm), img_ (img), pcX_ (0), pcY_ (0) { oconfig_ = OConfig::getInstance (); } @@ -26,13 +26,13 @@ void Skittle::pca (Zone &zone) { // Agrandissement de la zone de recherche - const int grow = 30; + const int grow = oconfig_->skittleGrow; int ymin = minWithBorder (zone.ymin - grow, 0); int ymax = maxWithBorder (zone.ymax + grow, img_->height_); int xmin = minWithBorder (zone.xmin - grow, 0); int xmax = maxWithBorder (zone.xmax + grow, img_->width_); /// Initialisation du saut de point - int jump = oconfig_->jumpPointDist/5; + int jump = oconfig_->jumpPointDist/oconfig_->skittleDivJump; if (!jump) jump = 1; // Parcours d'une partie des pixels de l'image int tmpY; @@ -48,14 +48,9 @@ Skittle::pca (Zone &zone) } } // Calcul de la composante principale - for (std::vector::iterator iter = l.begin (); iter != l.end (); ++iter) - std::cout << (*iter)[0] << " " << (*iter)[1] << std::endl; Hotelling hote (l); hote.eigenVectors (); - double i, j; - hote.getPC (i, j); - hote.show (); - std::cout << "PC : " << i << " " << j << std::endl; + hote.getPC (pcX_, pcY_); } /// Utilisé pour la recherche de la courbure, cherche le point le plus haut @@ -63,32 +58,53 @@ int Skittle::climb (const int startX, int startY, const int color) { while (segm_->giveColor (img_->tabData_ + ((startY*img_->width_ + startX) * 3), true, true) == color) - { -// std::cout << startX << " " << startY << std::endl; --startY; - } return startY; } +/// Vérifie qu'un catadiopre est à proximité +int +Skittle::isReflectBand (Zone &zone, std::vector &listReflectBand) +{ + // Test les variables de composantes principales + if (!pcX_ && !pcY_ && listReflectBand.size ()) + { + // Parcours la liste des catadiopres + for (std::vector::iterator iter = listReflectBand.begin (); + iter != listReflectBand.end (); ++iter) + { + // Test la distance cartésienne + if (dist (iter->centerx, iter->centery, zone.centerx, zone.centery)) + // Test la distance orthogonale + if (orthoDist (iter->centerx - zone.centerx, iter->centery - zone.centery, + pcX_, pcY_)) + return 1; + + } + } + return 0; +} + /// Recherche de du côté de la courbure Skittle::BendType Skittle::bend (Zone &zone) { /// Border - const int border = 20; + const int border = oconfig_->skittleBorder; /// Initialisation du saut de point - int jump = oconfig_->jumpPointDist/5; + int jump = oconfig_->jumpPointDist/oconfig_->skittleDivJump; if (!jump) jump = 1; /// Initialisation du point de départ - const int startY = (int)(zone.ymin + (zone.ymax - zone.ymin) * 0.25); + const int startY = minWithBorder ((int)(zone.ymin + (zone.ymax - zone.ymin) * 0.25), 0); /// Point supérieur de la quille int upperPoint; /// Recherche du premier et du dernier point int firstPoint = climb (maxWithBorder (zone.xmin + border, img_->width_), startY, zone.color); int lastPoint = climb (minWithBorder (zone.xmax - border, 0), startY, zone.color); int limitPoint = firstPoint > lastPoint ? firstPoint : lastPoint; - std::cout << firstPoint << " " << lastPoint << " " << limitPoint << std::endl; + std::cout << " " << firstPoint << " " << lastPoint << " " << limitPoint << std::endl; int above = 0; int below = 0; + std::cout << " "; /// Parcours des autres points for (int i = zone.xmin + border + jump; i < zone.xmax - border - jump; i+=jump) { @@ -98,31 +114,40 @@ Skittle::bend (Zone &zone) else ++above; } std::cout << std::endl; - const int score = (int)((zone.xmax - zone.xmin - 2*border) / jump * 0.90) - 2; + const int score = (int)((zone.xmax - zone.xmin - 2*border) / jump * oconfig_->skittleScoreBendRatio) - 2; BendType bending = error; if (above > score) bending = up; else if (below > score) bending = down; - std::cout << "courb " << bending << std::endl; return bending; } /// Analyse la zone bool -Skittle::analyse (Zone &zone) +Skittle::analyse (Zone &zone, std::vector &listReflectBand) { // group est partiel ? // if (zone.partial) // quille verticale sur l'image ? - if ((zone.ymax - zone.ymin)/(double)(zone.xmax - zone.xmin) > 1.1) + if ((zone.ymax - zone.ymin)/(double)(zone.xmax - zone.xmin) > oconfig_->skittleVerticalRatio) { std::cout << "vertical !!!" << std::endl; // debout ou couché ? - bend (zone); + bend_ = bend (zone); + isReflectBand (zone, listReflectBand); } else // calcul de l'orientation pca (zone); return true; } + +/// Affiche les infos sur la quille +void +Skittle::show () const +{ + std::cout << " position : " << (bend_ == up ? "up" + : (bend_ == down ? "down" : "error")) << "\n"; + std::cout << " orientation : " << pcX_ << ", " << pcY_ << std::endl; +} diff --git a/2005/i/robert/src/ovision/see/skittle.hh b/2005/i/robert/src/ovision/see/skittle.hh index d2c5dbe..ebdeb6f 100644 --- a/2005/i/robert/src/ovision/see/skittle.hh +++ b/2005/i/robert/src/ovision/see/skittle.hh @@ -24,6 +24,7 @@ #define skittle_h #include +#include #include "segm.hh" #include "oconfig.hh" @@ -39,6 +40,10 @@ class Skittle OConfig *oconfig_; /// Classe img Img *img_; + /// Composante principale + double pcX_, pcY_; + /// Position + double bend_; public: /// debout/couché/erreur @@ -48,7 +53,9 @@ class Skittle /// Destructeur ~Skittle (void); /// Analyse d'une zone - bool analyse (Zone &zone); + bool analyse (Zone &zone, std::vector &listReflectBand); + /// Affiche les infos sur la quille + void show () const; private: /// Recherche de la composante principale @@ -57,10 +64,17 @@ class Skittle BendType bend (Zone &zone); /// Utilisé pour la recherche de la courbure, cherche le point le plus haut int climb (const int startX, const int startY, const int color); + /// Vérifie qu'un catadiopre est à proximité + int isReflectBand (Zone &zone, std::vector &listReflectBand); /// Renvoie le minimum en fonction d'une bordure inline int minWithBorder (int n, int min) {return n > min ? n : min;} /// Renvoie le maximum en fonction d'une bordure inline int maxWithBorder (int n, int max) {return n < max ? n : max;} + /// Distance cartésienne + inline double dist (double x1, double x2, double y1, double y2) {return sqrt (x1*x2 + y1*y2);} + /// Distance orthogonale à une droite + inline double orthoDist (double v1x, double v1y, double v2x, double v2y) + {return ((v1x*v2y - v2x*v1y) / sqrt (v2x*v2x + v2y*v2y));} }; #endif // skittle_h diff --git a/2005/i/robert/src/ovision/ui/live.cc b/2005/i/robert/src/ovision/ui/live.cc index c7b8b09..bd5e680 100644 --- a/2005/i/robert/src/ovision/ui/live.cc +++ b/2005/i/robert/src/ovision/ui/live.cc @@ -1,4 +1,4 @@ -// comm.cc - Classe Live +// live.cc - Classe Live // robert - Programme du robot APBteam // Copyright (C) 2005 Olivier Gaillard @@ -56,6 +56,7 @@ Live::init (const Image::PixelFormat pf, const char *filename, Video4Linux *r; r = new Video4Linux ("/dev/video", pf); r->calibrate (); + r->setAdaptive (0); reader_ = reinterpret_cast (r); } break; @@ -153,7 +154,7 @@ Live::reloadConfig (const char *filename) void Live::segmAndGroup (const int numColorToShow) { - std::cout << numColorToShow << std::endl; + // Création des groupes delete group; group = new Group (img, segm); diff --git a/2005/i/robert/src/ovision/ui/live.hh b/2005/i/robert/src/ovision/ui/live.hh index 7023428..b590364 100644 --- a/2005/i/robert/src/ovision/ui/live.hh +++ b/2005/i/robert/src/ovision/ui/live.hh @@ -77,9 +77,9 @@ class Live const unsigned width=360, const unsigned height=296); /// Accessors void setColorToFind (const int color) {colorToFind_ = color;} - + private: - ImageInput imgInput_; + ImageInput imgInput_; }; -- cgit v1.2.3