// magnifier.cc - Classe Magnifier // robert - Programme du robot APBteam // Copyright (C) 2005 Olivier Gaillard #include #include "magnifier.hh" #include "hotelling.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; } } Zone &z = itemList_[Group::redSkittle][0]; isSkittle (z); } /// Test si l'object s'agit d'un doublon bool Magnifier::checkIsUnique (const Zone &zone) { 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)) { // 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 bool Magnifier::isSkittle (Zone &zone) { // Agrandissement de la zone de recherche const int grow = 20; int ymin = (zone.ymin - grow); ymin = (ymin > 0) ? ymin : 0; int ymax = (zone.ymax + grow); ymax = (ymax < img_->height_) ? ymax : img_->height_; int xmin = (zone.xmin - grow); xmin = (xmin > 0) ? xmin : 0; int xmax = (zone.xmax + grow); xmax = (xmax < img_->width_) ? xmax : img_->width_; // Parcours d'une partie des pixels de l'image int tmpY; int jump = oconfig_->jumpPointDist/5; if (!jump) jump = 1; std::vector l; for (int y = zone.ymin - grow; y < zone.ymax + grow; y += jump) { tmpY = y*img_->width_; for (int x=zone.xmin - grow; x < zone.xmax + grow; x += jump) if (segm_->giveColor (img_->tabData_ + ((tmpY + x) * 3), true, true) == zone.color) { Hpoint h (x, y); l.push_back (h); } } // 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; 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; }