// skittle.cc - Classe Skittle // robert - Programme du robot APBteam // Copyright (C) 2005 Olivier Gaillard /// @file skittle.cc Reconnaissance des objets quilles #include #include "skittle.hh" #include "hotelling.hh" /// Constructeur Skittle::Skittle (Img *img, Segm *segm) : segm_ (segm), img_ (img) { oconfig_ = OConfig::getInstance (); } /// Destructeur Skittle::~Skittle (void) { } /// Recherche de la composante principale void Skittle::pca (Zone &zone) { // Agrandissement de la zone de recherche const int grow = 30; 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; if (!jump) jump = 1; // Parcours d'une partie des pixels de l'image int tmpY; std::vector l; for (int y = ymin; y < ymax; y += jump) { tmpY = y*img_->width_; for (int x = xmin; x < xmax; 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; } /// 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) { // std::cout << startX << " " << startY << std::endl; --startY; } return startY; } /// Recherche de du côté de la courbure Skittle::BendType Skittle::bend (Zone &zone) { /// Border const int border = 20; /// Initialisation du saut de point int jump = oconfig_->jumpPointDist/5; if (!jump) jump = 1; /// Initialisation du point de départ const int startY = (int)(zone.ymin + (zone.ymax - zone.ymin) * 0.25); /// 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 above = 0; int below = 0; /// Parcours des autres points for (int i = zone.xmin + border + jump; i < zone.xmax - border - jump; i+=jump) { upperPoint = climb (i, startY, zone.color); std::cout << upperPoint << " "; if (upperPoint > limitPoint) ++below; else ++above; } std::cout << std::endl; const int score = (int)((zone.xmax - zone.xmin - 2*border) / jump * 0.90) - 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) { // group est partiel ? // if (zone.partial) // quille verticale sur l'image ? if ((zone.ymax - zone.ymin)/(double)(zone.xmax - zone.xmin) > 1.1) { std::cout << "vertical !!!" << std::endl; // debout ou couché ? bend (zone); } else // calcul de l'orientation pca (zone); return true; }