From fb075a07e3347a357e18b7df3795909b0d6f4918 Mon Sep 17 00:00:00 2001 From: gaillaro Date: Sat, 23 Apr 2005 18:58:44 +0000 Subject: * ajout détection des groupes de quilles * essai de detection des vis * detection verticalité --- 2005/i/robert/src/ovision/see/group.cc | 2 +- 2005/i/robert/src/ovision/see/group.hh | 8 ++ 2005/i/robert/src/ovision/see/hotelling.cc | 15 +++ 2005/i/robert/src/ovision/see/hotelling.hh | 1 + 2005/i/robert/src/ovision/see/img.hh | 4 + 2005/i/robert/src/ovision/see/magnifier.cc | 186 ++++++++++++++++++++------ 2005/i/robert/src/ovision/see/magnifier.hh | 12 +- 2005/i/robert/src/ovision/see/oconfig.cc | 52 +++---- 2005/i/robert/src/ovision/see/oconfig.hh | 4 + 2005/i/robert/src/ovision/see/ovision.cc | 31 +---- 2005/i/robert/src/ovision/see/segm.hh | 2 +- 2005/i/robert/src/ovision/see/segmLearn.cc | 4 +- 2005/i/robert/src/ovision/see/segmLearn.hh | 2 +- 2005/i/robert/src/ovision/see/segmTable.cc | 4 +- 2005/i/robert/src/ovision/see/segmTable.hh | 2 +- 2005/i/robert/src/ovision/see/skittle.cc | 163 ++++++++++++++++++---- 2005/i/robert/src/ovision/see/skittle.hh | 18 ++- 2005/i/robert/src/ovision/see/test_ovision.cc | 8 +- 2005/i/robert/src/ovision/ui/live.cc | 4 +- 2005/i/robert/src/ovision/ui/ui.cc | 1 + 20 files changed, 386 insertions(+), 137 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 e18379f..0fd8670 100644 --- a/2005/i/robert/src/ovision/see/group.cc +++ b/2005/i/robert/src/ovision/see/group.cc @@ -111,7 +111,7 @@ void Group::jumpPoints (const std::vector &colorList) tmpY = y*img_->width_; for (int x=0; xwidth_; x+=oconfig_->jumpPointDist) { - curColor = segm_->giveColor (img_->tabData_ + ((tmpY + x) * 3), true, true); + curColor = segm_->giveColor (img_->tabData_ + ((tmpY + x) * 3), true, true, true); for (iter = colorList.begin (); iter != colorList.end (); ++iter) if ((iter->color >= 0) && (iter->color == curColor)) { diff --git a/2005/i/robert/src/ovision/see/group.hh b/2005/i/robert/src/ovision/see/group.hh index 6d5502a..ff5cae7 100644 --- a/2005/i/robert/src/ovision/see/group.hh +++ b/2005/i/robert/src/ovision/see/group.hh @@ -49,6 +49,14 @@ struct Zone bool bottom; /// couleur de la zone int color; + /// quille verticale ? + bool vertical; + /// groupe de quille ou quille seule + bool alone; + /// ratio entre longueur verticale et horizontale + double ratio; + /// orientation + double pcX, pcY; }; /// Cree une liste chainee de zones correspondant aux balles diff --git a/2005/i/robert/src/ovision/see/hotelling.cc b/2005/i/robert/src/ovision/see/hotelling.cc index dbd0e72..0e83c2d 100644 --- a/2005/i/robert/src/ovision/see/hotelling.cc +++ b/2005/i/robert/src/ovision/see/hotelling.cc @@ -137,3 +137,18 @@ Hotelling::show () const << "\t" << e1_[0] << ", " << e1_[1] << "\n" << "\t" << e2_[0] << ", " << e2_[1] << std::endl; } + +void +Hotelling::get (double &x, double &y, double &x2, double &y2) +{ + if (val1_>val2_) + { + x = e1_[0]; y = e1_[1]; + x2 = e2_[0]; y2 = e2_[1]; + } + else + { + x = e2_[0]; y = e2_[1]; + x2 = e1_[0]; y2 = e1_[1]; + } +} diff --git a/2005/i/robert/src/ovision/see/hotelling.hh b/2005/i/robert/src/ovision/see/hotelling.hh index ba32027..b3c4081 100644 --- a/2005/i/robert/src/ovision/see/hotelling.hh +++ b/2005/i/robert/src/ovision/see/hotelling.hh @@ -60,6 +60,7 @@ class Hotelling /// Accessors void getPC (Hpoint &pca); void getPC (double &x, double &y); + void get (double &x, double &y, double &x2, double &y2); private: /// Calcul des eigenvalues diff --git a/2005/i/robert/src/ovision/see/img.hh b/2005/i/robert/src/ovision/see/img.hh index 750e629..43c6c76 100644 --- a/2005/i/robert/src/ovision/see/img.hh +++ b/2005/i/robert/src/ovision/see/img.hh @@ -56,6 +56,10 @@ class Img 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); + /// 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;} protected: /// tableau des couleurs bruts diff --git a/2005/i/robert/src/ovision/see/magnifier.cc b/2005/i/robert/src/ovision/see/magnifier.cc index 66db1b4..f26e367 100644 --- a/2005/i/robert/src/ovision/see/magnifier.cc +++ b/2005/i/robert/src/ovision/see/magnifier.cc @@ -22,6 +22,7 @@ Magnifier::Magnifier (Img *img, Segm *segm, Group::ZoneType aim) Magnifier::~Magnifier (void) { delete [] itemList_; + delete skittleList_; } @@ -57,30 +58,11 @@ Magnifier::analyse (std::vector &zoneList) || ((iter->ymax - iter->ymin) < oconfig_->minLengthZone)) continue; // Vérifie qu'il n'y a pas de doublon - if (!checkIsUnique (*iter)) + if (!checkIsUnique (*iter, itemList_)) 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; - case Group::reflectBand: - addItem (*iter); - break; - } + add (*iter, itemList_); } + while (scan ()); skittleList_->clear (); if (itemList_[aim_].size () != 0) { @@ -91,6 +73,8 @@ Magnifier::analyse (std::vector &zoneList) Skittle *s = isSkittle (*iter); if (s) { + showZone (*iter); + s->show (); skittleList_->push_back (*s); delete s; find = 1; @@ -101,29 +85,95 @@ Magnifier::analyse (std::vector &zoneList) return false; } +bool +Magnifier::scan () +{ + std::vector *newList = new std::vector[Group::nbZoneType]; + for (int i=0; i ::iterator iter = itemList_[i].begin (); iter != itemList_[i].end (); ++iter) + { + if (!checkIsUnique (*iter, newList)) + continue; + add (*iter, newList); + } +// delete [] itemList_; + itemList_ = newList; + } + return false; +} + +void +Magnifier::add (Zone &zone, std::vector *list) +{ + switch (zone.id) + { + case Group::redSkittle: + if (isRedSkittle (zone)) addItem (zone, list); + break; + case Group::greenSkittle: + if (isGreenSkittle (zone)) addItem (zone, list); + break; + case Group::base: + if (isBase (zone)) addItem (zone, list); + break; + case Group::gap: + if (isGap (zone)) addItem (zone, list); + break; + case Group::border: + if (isBorder (zone)) addItem (zone, list); + break; + case Group::reflectBand: + addItem (zone, list); + break; + } +} + +bool +isInside (const Zone &z1, const Zone &z2) +{ + const int maxOut = 300; + int out = 0; + // test si le centre est à l'intérieur + if ((z1.centerx <= z2.xmax) && (z1.centerx >= z2.xmin) + && (z1.centery <= z2.ymax) && (z1.centery >= z2.ymin)) + { + return true; +// if (z1.xmax > z2.xmax ) out += z1.xmax - z2.xmax; +// if (z1.ymax > z2.ymax ) out += z1.ymax - z2.ymax; +// if (z1.xmin < z2.xmin ) out += z2.xmin - z1.xmin; +// if (z1.ymin < z2.ymin ) out += z2.ymin - z1.ymin; +// if (out < maxOut) return true; + } + return false; +} /// Test si l'object s'agit d'un doublon bool -Magnifier::checkIsUnique (const Zone &zone) +Magnifier::checkIsUnique (const Zone &zone, std::vector *list) { - const int uniqueness = 200; - 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)) + for (std::vector::iterator iter = list[zone.id].begin (); + iter != list[zone.id].end (); ++iter) + if (((abs (zone.centerx - iter->centerx) < oconfig_->magUniqueness) + || (abs (zone.centery - iter->centery) < oconfig_->magUniqueness))) { - // 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; + if (isInside (zone, *iter) || isInside (*iter, zone)) + // || (areBound (zone, *iter))) + { + // 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 Skittle* Magnifier::isSkittle (Zone &zone) @@ -131,7 +181,6 @@ Magnifier::isSkittle (Zone &zone) Skittle *s = new Skittle (img_, segm_); if (s->analyse (zone, itemList_[Group::reflectBand])) { - s->show (); return s; } else @@ -184,13 +233,12 @@ Magnifier::isGap (const Zone &zone) const } /// Ajout d'un objet - void -Magnifier::addItem (Zone &zone) +Magnifier::addItem (Zone &zone, std::vector *list) { // TODO remplir les flags : partial, ... zone.area = (zone.xmax - zone.xmin) * (zone.ymax - zone.ymin); - itemList_[zone.id].push_back (zone); + list[zone.id].push_back (zone); } @@ -204,3 +252,61 @@ Magnifier::showItems (const Group::ZoneType type) const << iter->ymin << " " << iter->ymax << "\n"; std::cout << std::endl; } + + +/// Test si les zones sont liées +bool +Magnifier::areBound (const Zone &z1, const Zone &z2) +{ + /// Ratio demandé pour la liaison + const double ratioBound = 0.95; + /// Coeff directeur de la droite reliant les 2 zones + int yCenterDiff = z1.centery - z2.centery; + int xCenterDiff = z1.centerx - z2.centerx; + double a, b; + if (yCenterDiff != 0) + { + a = yCenterDiff / (double)xCenterDiff; + b = z1.centery - a * z1.centerx; + } + else + { + a = 0; + b = z1.centery; + } + int min, max; + if (xCenterDiff < 0) + { + min = z1.centerx; + max = z2.centerx; + } + else + { + min = z2.centerx; + max = z1.centerx; + } + /// Parcours des x entre les 2 zones + int equal = 0; + int y; + for (int x = min; x < max; ++x) + { + y = img_->maxWithBorder (img_->minWithBorder ((int)(a*x+b), 0), img_->height_);; + if (segm_->giveColor (img_->tabData_ + ((y*img_->width_+x) * 3), true, true) == z1.color) + ++equal; + } + /// Retour avec marge d'erreur + if (equal >= (max - min)*ratioBound-2) + return true; + return false; +} + +void +Magnifier::showZone (const Zone &z) const +{ + std::cout << "------------------------------------------------------------------\n"; + std::cout << " position : " << z.xmin << ", " << z.xmax << ", " << z.ymin << ", " << z.ymax << "\n"; + std::cout << " alone : " << z.alone << "\n"; + std::cout << " ratio/vertical: " << z.ratio << " " << (z.vertical?"vertical":"") << "\n"; +// std::cout << " orientation : " << z.pcX_ << ", " << z.pcY_ << "\n"; + std::cout << " partial : " << z.partial << "\n"; +} diff --git a/2005/i/robert/src/ovision/see/magnifier.hh b/2005/i/robert/src/ovision/see/magnifier.hh index 184b790..464e20f 100644 --- a/2005/i/robert/src/ovision/see/magnifier.hh +++ b/2005/i/robert/src/ovision/see/magnifier.hh @@ -45,7 +45,7 @@ class Magnifier Group::ZoneType aim_; /// Liste de quilles std::vector *skittleList_; - + public: /// Constructeur Magnifier (Img *img, Segm *segm, Group::ZoneType aim); @@ -58,14 +58,20 @@ class Magnifier /// Renvoie une liste d'objet std::vector& getItemList (Group::ZoneType type) {return itemList_[type];} + /// Affiche des infos sur une zone + void showZone (const Zone &z) const; private: /// Ajout d'un objet - void addItem (Zone &zone); + void addItem (Zone &zone, std::vector *list); /// Test si l'object s'agit d'un doublon - bool checkIsUnique (const Zone &zone); + bool checkIsUnique (const Zone &zone, std::vector *list); + /// Test si les zones sont liées + bool areBound (const Zone &z1, const Zone &z2); /// Test la validité des objects Skittle* isSkittle (Zone &zone); + void add (Zone &zone, std::vector *list); + bool scan (); bool isRedSkittle (const Zone &zone) const; bool isGreenSkittle (const Zone &zone) const; bool isBase (const Zone &zone) const; diff --git a/2005/i/robert/src/ovision/see/oconfig.cc b/2005/i/robert/src/ovision/see/oconfig.cc index 41337a8..60f38e1 100644 --- a/2005/i/robert/src/ovision/see/oconfig.cc +++ b/2005/i/robert/src/ovision/see/oconfig.cc @@ -48,33 +48,35 @@ OConfig::parse (const char *var, const char *arg) 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); + 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_threshold_output") nnThresholdOutput = atoi(arg); - else if (varName == "NN_lum_inosity_influence") nnInfluLum = atof(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); - 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); + 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); + 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); + else if (varName == "Mag_uniqueness") magUniqueness = atoi (arg); + else if (varName == "Cam_brightness") brightness = atoi (arg); } diff --git a/2005/i/robert/src/ovision/see/oconfig.hh b/2005/i/robert/src/ovision/see/oconfig.hh index 39efd18..54dbfec 100644 --- a/2005/i/robert/src/ovision/see/oconfig.hh +++ b/2005/i/robert/src/ovision/see/oconfig.hh @@ -112,6 +112,8 @@ class OConfig int spaceNbDistPoint; //float one_nn_learning_rate; //int one_nn_learning_iteration; + // Distance min pour que deux zones soient distinctes + int magUniqueness; /////////////////////////////// UI //////////////////////////////////////////////////////////////// /// tableau d'index des couleurs a melanger (merge) int *index; @@ -121,6 +123,8 @@ class OConfig int uiGroupToDisplay; /// Mode de couleurs des images chargées Image::PixelFormat inputColor; + /// Luminosité utilisée pour la caméra + int brightness; /////////////////////////////// UI //////////////////////////////////////////////////////////////// /// Bordure de la zone utilisée pour rétrécir la quille avant l'analyse de la /// courbure de celle-ci diff --git a/2005/i/robert/src/ovision/see/ovision.cc b/2005/i/robert/src/ovision/see/ovision.cc index 9a74c21..d6a8b0b 100644 --- a/2005/i/robert/src/ovision/see/ovision.cc +++ b/2005/i/robert/src/ovision/see/ovision.cc @@ -17,9 +17,7 @@ OVision::~OVision () delete segm_; delete group_; delete mag_; -// delete map_; -// delete space_; -// delete socket_; + delete space_; } /// Iniialisatoin de toutes les classes @@ -31,29 +29,24 @@ OVision::init (const Group::ZoneType aim) oconfig_ = new OConfig; img_ = new Img; // Initialisation caméra - v4l_ = new Video4Linux ("/dev/video", oconfig_->inputColor); + v4l_ = new Video4Linux ("/dev/video", oconfig_->inputColor, oconfig_->brightness); v4l_->calibrate (); + v4l_->setAdaptive (0); // Prendre une image pour que la taille de l'image soit configuré img_->load (*v4l_); colorTab_ = new ColorTable; segm_ = new SegmTable (*colorTab_); + segm_->setMode (oconfig_->inputColor); group_ = new Group (img_, segm_); mag_ = new Magnifier (img_, segm_, aim_); // Mode de couleur utilisé pour les la segmentation segm_->setMode (oconfig_->inputColor); space_ = new Space (img_->width_, img_->height_); -// map_ = new Map (space); // Calibration des longueurs space_->addSetupPoint (314, 6, 100, 400); space_->addSetupPoint (237, 224, 100, 900); space_->addSetupPoint (275, 113, 100, 550); space_->setup (0.00891157, 0.258144, 403.801); - // Ouverture ou création de la table de couleur - /// Initialisation des socket_s - // socket_ = new SocketClient ("10.42.51.2" , 106560*3); - // socket_->Init (); - - // std::cout << "Chargement OVision ................ OK" << std::endl; } /// Prends une image avec la caméra @@ -82,18 +75,6 @@ OVision::update () space->GetLoc (x, y, x, y); } */ - // Mets à jour la map_ - /* map_->AddBallsToMap (group_); - double balX, balY; - if (map_->GetCurBallPos (balX, balY)) - std::cout << "Balle Courante: " << balX << " " << balY << std::endl; - if (map_->IsTree ()) - { - double treeX, treeY; - map_->GetTreePos (treeX, treeY); - std::cout << "Tree: " << treeX << " " << treeY << std::endl; - } - */ } /// Affiche d'info sur l'update @@ -103,8 +84,8 @@ OVision::showInfo () const std::cout << "-----------------------------------------------------------------" << std::endl; std::cout << "image n°" << step_ << std::endl; // Info sur les zones trouvées - group_->showZones(); - mag_->showItems (Group::redSkittle); +// group_->showZones(); +// mag_->showItems (Group::redSkittle); std::cout << "-------------\n" << std::endl; std::cout << "-------------\n" << std::endl; } diff --git a/2005/i/robert/src/ovision/see/segm.hh b/2005/i/robert/src/ovision/see/segm.hh index 290ecf1..44221b0 100644 --- a/2005/i/robert/src/ovision/see/segm.hh +++ b/2005/i/robert/src/ovision/see/segm.hh @@ -40,7 +40,7 @@ class 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; + virtual unsigned char giveColor (const unsigned char *x, const bool testOutputMax = false, const bool indexProcess = false, const bool lumFlag = false) = 0; /// Segmentation de l'image void segmImg (Img *img); /// Segmentation de l'image permettant d'isoler une couleur diff --git a/2005/i/robert/src/ovision/see/segmLearn.cc b/2005/i/robert/src/ovision/see/segmLearn.cc index 627f656..b2a0a83 100644 --- a/2005/i/robert/src/ovision/see/segmLearn.cc +++ b/2005/i/robert/src/ovision/see/segmLearn.cc @@ -173,9 +173,9 @@ SegmLearn::findColorNN (const unsigned char *x, const bool testOutputMax) const /// @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) +SegmLearn::giveColor (const unsigned char *x, const bool testOutputMax, const bool nodeProcess, const bool lumFlag) { - if (lumPos_ >= 0) addLum (x[lumPos_]); + if (lumFlag && (lumPos_ >= 0)) addLum (x[lumPos_]); if (nodeProcess) return index_ [findColorNN (x, testOutputMax)]; else diff --git a/2005/i/robert/src/ovision/see/segmLearn.hh b/2005/i/robert/src/ovision/see/segmLearn.hh index 3d0f564..464e233 100644 --- a/2005/i/robert/src/ovision/see/segmLearn.hh +++ b/2005/i/robert/src/ovision/see/segmLearn.hh @@ -41,7 +41,7 @@ class SegmLearn : public Segm /// 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); + virtual unsigned char giveColor (const unsigned char *x, const bool testUndefined = false, const bool indexProcess = false, const bool lumFlag = false); private: /// Genere des poids pour un noeud diff --git a/2005/i/robert/src/ovision/see/segmTable.cc b/2005/i/robert/src/ovision/see/segmTable.cc index 9f76726..ff428e2 100644 --- a/2005/i/robert/src/ovision/see/segmTable.cc +++ b/2005/i/robert/src/ovision/see/segmTable.cc @@ -20,9 +20,9 @@ SegmTable::SegmTable (ColorTable &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) +SegmTable::giveColor (const unsigned char *x, const bool testOutputMax, const bool index_Process, const bool lumFlag) { - if (lumPos_ >= 0) addLum (x[lumPos_]); + if (lumFlag && (lumPos_ >= 0)) addLum (x[lumPos_]); // if (index_Process) return index_ [tab_[(int) (x[0] * ColorTable::colorTabSize2 + x[1] * ColorTable::colorTabSize + x[2]) ]]; // else diff --git a/2005/i/robert/src/ovision/see/segmTable.hh b/2005/i/robert/src/ovision/see/segmTable.hh index 4051a43..770e4ee 100644 --- a/2005/i/robert/src/ovision/see/segmTable.hh +++ b/2005/i/robert/src/ovision/see/segmTable.hh @@ -35,7 +35,7 @@ class SegmTable : public Segm /// 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); + virtual unsigned char giveColor (const unsigned char *x, const bool testOutputMax = false, const bool indexProcess = false, const bool lumFlag = false); }; #endif // segmTable_h diff --git a/2005/i/robert/src/ovision/see/skittle.cc b/2005/i/robert/src/ovision/see/skittle.cc index 1253e26..047455e 100644 --- a/2005/i/robert/src/ovision/see/skittle.cc +++ b/2005/i/robert/src/ovision/see/skittle.cc @@ -27,10 +27,10 @@ Skittle::pca (const Zone &zone) { // Agrandissement de la zone de recherche 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_); + int ymin = img_->minWithBorder (zone.ymin - grow, 0); + int ymax = img_->maxWithBorder (zone.ymax + grow, img_->height_); + int xmin = img_->minWithBorder (zone.xmin - grow, 0); + int xmax = img_->maxWithBorder (zone.xmax + grow, img_->width_); /// Initialisation du saut de point int jump = oconfig_->jumpPointDist/oconfig_->skittleDivJump; if (!jump) jump = 1; @@ -43,6 +43,7 @@ Skittle::pca (const Zone &zone) for (int x = xmin; x < xmax; x += jump) if (segm_->giveColor (img_->tabData_ + ((tmpY + x) * 3), true, true) == zone.color) { + *f2 << x << " " << y << std::endl; Hpoint h (x, y); l.push_back (h); } @@ -50,15 +51,19 @@ Skittle::pca (const Zone &zone) // Calcul de la composante principale Hotelling hote (l); hote.eigenVectors (); - hote.getPC (pcX_, pcY_); + hote.get (pcX_, pcY_, pc2X_, pc2Y_); } /// Utilisé pour la recherche de la courbure, cherche le point le plus haut int Skittle::climb (const int startX, int startY, const int color) { - while (segm_->giveColor (img_->tabData_ + ((startY*img_->width_ + startX) * 3), true, true) == color) + while ((segm_->giveColor (img_->tabData_ + ((startY*img_->width_ + startX) * 3), true, true) == color) + && (startY > 0)) + { --startY; + *f << startX << " " << startY << "\n"; + } return startY; } @@ -99,30 +104,41 @@ Skittle::bend (const Zone &zone) /// Border const int border = oconfig_->skittleBorder; /// Initialisation du saut de point - int jump = oconfig_->jumpPointDist/oconfig_->skittleDivJump; + int jump = 1; //oconfig_->jumpPointDist/oconfig_->skittleDivJump; if (!jump) jump = 1; /// Initialisation du point de départ - const int startY = minWithBorder ((int)(zone.ymin + (zone.ymax - zone.ymin) * 0.25), 0); + const int startY = img_->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; + int firstPoint = img_->maxWithBorder (zone.xmin + border, img_->width_); + int lastPoint = img_->minWithBorder (zone.xmax - border, 0); +// int limitPoint = firstPoint > lastPoint ? firstPoint : lastPoint; + + int limitPoint = climb (zone.centerx, startY, zone.color); +// std::cout << " " << firstPoint << " " << lastPoint << " " << limitPoint << std::endl; int above = 0; int below = 0; - std::cout << " "; +// std::cout << " "; + int last = 0; + int trash = 0; /// Parcours des autres points - for (int i = zone.xmin + border + jump; i < zone.xmax - border - jump; i+=jump) + for (int i = firstPoint + jump; i < lastPoint - jump; i+=jump) { upperPoint = climb (i, startY, zone.color); - std::cout << upperPoint << " "; - if (upperPoint > limitPoint) ++below; - else ++above; + if (last == upperPoint) + ++trash; + else + { +// std::cout << upperPoint << " "; + if (upperPoint > limitPoint) ++below; + else ++above; + } + last = upperPoint; } - std::cout << std::endl; - const int score = (int)((zone.xmax - zone.xmin - 2*border) / jump * oconfig_->skittleScoreBendRatio) - 2; +// std::cout << std::endl; + const int score = (int)((lastPoint - firstPoint - trash) / jump * oconfig_->skittleScoreBendRatio) - 2; +// std::cout << "-- " << above << " " << below << " " << score << std::endl; Pos bending = error; if (above > score) bending = up; else if (below > score) bending = down; @@ -132,32 +148,129 @@ Skittle::bend (const Zone &zone) /// Analyse la zone bool -Skittle::analyse (const Zone &zone, const std::vector &listReflectBand) +Skittle::analyse (Zone &zone, const std::vector &listReflectBand) { + // delete f; delete f2; + f = new std::ofstream ("data", std::ios_base::trunc); + f2 = new std::ofstream ("data2", std::ios_base::trunc); // group est partiel ? // if (zone.partial) // quille verticale sur l'image ? - if ((zone.ymax - zone.ymin)/(double)(zone.xmax - zone.xmin) > oconfig_->skittleVerticalRatio) + zone.ratio = (zone.ymax - zone.ymin)/(double)(zone.xmax - zone.xmin); + if (zone.ratio > oconfig_->skittleVerticalRatio) { - std::cout << "vertical !!!" << std::endl; + zone.vertical = true; // debout ou couché ? - bend_ = bend (zone); + //bend_ = bend (zone); whereIsReflectBand (zone, listReflectBand); } else + { + zone.vertical = false; + bend_ = down; // calcul de l'orientation pca (zone); + } + + bend (zone); + pca (zone); + feet_ = whereIsBottom (zone); + if (checkArea (zone) == 1) + zone.alone = true; + else zone.alone = false; + + + f->close (); + f2->close (); return true; } + +/// Test si la zone contient les vis +double +Skittle::isBottom (const Zone &zone, const Pos pos) +{ + int newCenterx, newCentery; + // Recherche de la zone à analyser + int shiftx = (int)(pcX_*(zone.xmax-zone.centerx)); + int shifty = (int)(1.2*pcY_*(zone.ymax-zone.centery)); + if (((pos == down) && (pcY_ > 0)) || ((pos == up) && (pcY_ <0))) + { + shiftx *= -1; + shifty *= -1; + } + newCenterx = (int)(zone.centerx - shiftx); + newCentery = (int)(zone.centery - shifty); + //std::cout << "--- " << (zone.xmax - zone.xmin) * (zone.ymax - zone.ymin); + //std::cout << "%%%% " << newCenterx << " " << newCentery << std::endl; + //std::cout << "%%% " << zone.centerx << " " << zone.centery << std::endl; + //std::cout << "%% " << zone.xmin << " " << zone.xmax << " " << zone.ymin << " " << zone.ymax << std::endl; + // Recherche des extrémités + int startx = (int)(newCenterx - (zone.xmax - zone.xmin)*pc2X_); + int endx = (int)(newCenterx + (zone.xmax - zone.xmin)*pc2X_); + //std::cout << "% " << startx << " " << endx << std::endl; + // Test si la zone est valide + if ((startx < 0) || (endx > img_->width_)) + return -1; + // Parcours de la zone + int last = -1; + int diff = 0; + int y, color; + for (int x=startx; x < endx; ++x) + { + y = (int)(newCentery + (x - newCenterx)/2*pc2Y_); + if ((y < 0) || (y > img_->height_)) + return -1; + color = segm_->giveColor (img_->tabData_ + ((y*img_->width_ + x) * 3), true, true); + if (color != last) + { + ++diff; + last = color; + } + } + //std::cout << diff << std::endl; + return diff; +} + +/// Cherche les vis de la quille +Skittle::Pos +Skittle::whereIsBottom (const Zone &zone) +{ + double isUp, isDown; + isUp = isBottom (zone, up); + isDown = isBottom (zone, down); + if ((isUp == -1) || (isDown == -1)) + return error; + if (isUp > isDown) + return up; + else if (isDown> isUp) + return down; + return error; +} + +/// Verifie la cohérence de la taille de la quille +int +Skittle::checkArea (const Zone &zone) +{ + if (zone.ymax < 150) + if ((zone.xmax - zone.xmin) * (zone.ymax - zone.ymin) > 14000) + return 2; + else if (zone.ymax >= 150) + if ((zone.xmax - zone.xmin) * (zone.ymax - zone.ymin) > 19000) + return 2; + return 1; +} + /// Affiche les infos sur la quille void Skittle::show () const { - std::cout << " position : " << (bend_ == up ? "up" - : (bend_ == down ? "down" : "error")) << "\n"; + std::cout << " position : " << (bend_ == up ? "debout" + : (bend_ == down ? "couché" : "error")) << "\n"; std::cout << " orientation : " << pcX_ << ", " << pcY_ << "\n"; std::cout << " catadiopre: " << (reflectBand_ == up ? "up" : (reflectBand_ == down ? "down" : (reflectBand_ == farAway ? "farAway" : "error"))) << std::endl; + std::cout << " vis : " << (feet_ == up ? "up" + : (feet_ == down ? "down" : "error")) << std::endl; } diff --git a/2005/i/robert/src/ovision/see/skittle.hh b/2005/i/robert/src/ovision/see/skittle.hh index b41d154..678d3b7 100644 --- a/2005/i/robert/src/ovision/see/skittle.hh +++ b/2005/i/robert/src/ovision/see/skittle.hh @@ -25,6 +25,7 @@ #include #include +#include #include "segm.hh" #include "oconfig.hh" @@ -42,20 +43,25 @@ class Skittle Img *img_; /// Composante principale double pcX_, pcY_; + double pc2X_, pc2Y_; /// Enum pos enum Pos {up, down, farAway, error}; /// Courbure Pos bend_; + /// Sens + Pos feet_; /// Position de la bande réfléchissante Pos reflectBand_; + std::ofstream *f, *f2; + public: /// Constructeur Skittle (Img *img, Segm *segm); /// Destructeur ~Skittle (void); /// Analyse d'une zone - bool analyse (const Zone &zone, const std::vector &listReflectBand); + bool analyse (Zone &zone, const std::vector &listReflectBand); /// Affiche les infos sur la quille void show () const; /// Recupère les données @@ -71,10 +77,12 @@ class Skittle int climb (const int startX, const int startY, const int color); /// Vérifie qu'un catadiopre est à proximité Pos whereIsReflectBand (const Zone &zone, const 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;} + /// Cherche les vis de la quille + Pos whereIsBottom (const Zone &zone); + /// Test si la zone contient les vis + double isBottom (const Zone &zone, const Pos pos); + /// Verifie la cohérence de la taille de la quille + int checkArea (const Zone &zone); /// Distance cartésienne inline const double dist (const double x1, const double x2, const double y1, const double y2) {return sqrt (x1*x2 + y1*y2);} diff --git a/2005/i/robert/src/ovision/see/test_ovision.cc b/2005/i/robert/src/ovision/see/test_ovision.cc index 82a236c..88cb6fe 100644 --- a/2005/i/robert/src/ovision/see/test_ovision.cc +++ b/2005/i/robert/src/ovision/see/test_ovision.cc @@ -32,12 +32,12 @@ main(int argv, char **argc) // Analyse une image ovision.update (); // Affiche d'info sur l'update - ovision.showInfo (); +// ovision.showInfo (); // Affiche les coordonnées de la première balle double x, y; - if (ovision.getBall (x, y)) - std::cout << x <<"----" << y << std::endl; - sleep (1); +// if (ovision.getBall (x, y)) +// std::cout << x <<"----" << y << std::endl; + sleep (5); } return 0; } diff --git a/2005/i/robert/src/ovision/ui/live.cc b/2005/i/robert/src/ovision/ui/live.cc index bd5e680..62bd1ad 100644 --- a/2005/i/robert/src/ovision/ui/live.cc +++ b/2005/i/robert/src/ovision/ui/live.cc @@ -54,7 +54,7 @@ Live::init (const Image::PixelFormat pf, const char *filename, case cam: { Video4Linux *r; - r = new Video4Linux ("/dev/video", pf); + r = new Video4Linux ("/dev/video", pf, oconfig_->brightness); r->calibrate (); r->setAdaptive (0); reader_ = reinterpret_cast (r); @@ -73,7 +73,7 @@ Live::init (const Image::PixelFormat pf, const char *filename, segm = new SegmLearn; segm->setMode (pf); segm->buildNN (oconfig->nnNbColor, Segm::loadFromFile); - mag = new Magnifier (img, segm); + mag = new Magnifier (img, segm, Group::ZoneType (oconfig->uiGroupToDisplay)); segmAndGroup (); // Affichage de l'image pilote avec la couleur d'aquisition et en RGB tex[1] = loadImage (img->width_, img->height_, data[0], tex[1]); diff --git a/2005/i/robert/src/ovision/ui/ui.cc b/2005/i/robert/src/ovision/ui/ui.cc index 7183c4c..b91d9d5 100644 --- a/2005/i/robert/src/ovision/ui/ui.cc +++ b/2005/i/robert/src/ovision/ui/ui.cc @@ -1098,6 +1098,7 @@ UI::menu () case 8: // Regeneration de poids int nbColor; nbColor = chooseColor (NB_COULEUR, oconfig->nnNbColor); + oconfig->nnNbColor = nbColor; newNN (nbColor); break; -- cgit v1.2.3