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/magnifier.cc | 186 ++++++++++++++++++++++------- 1 file changed, 146 insertions(+), 40 deletions(-) (limited to '2005/i/robert/src/ovision/see/magnifier.cc') 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"; +} -- cgit v1.2.3