2013-07-19 4 views
0

Je l'exécution d'une vidéo dans laquelle je veux détecter 3 formes géométriques cercle de triangle et pentagone, et rien d'autre, ici un cadre de cette vidéo et le résultat que je reçois:extraction des formes géométriques avec OpenCV

source

le résultat correct

correct result

Un mauvais résultat de beaucoup.

Bad result

et voici mon code:

img =src; 
cv::Moments mom; 
cv::Mat result(img.size(),CV_8U,cv::Scalar(255)); 
cv::threshold(img,img,127,255,CV_THRESH_BINARY_INV); 
cv::findContours(img,contours,/*hiararchy,*/CV_RETR_LIST, CV_CHAIN_APPROX_NONE); 
for (int i=0; i<contours.size();i++){ 
    cv::approxPolyDP(cv::Mat(contours[i]),approx,(cv::arcLength(cv::Mat(contours[i]),true)*.02),true); 
switch(approx.size()){ 

      case 8: // should be a circle 
       cv::minEnclosingCircle(cv::Mat(contours[i]),center,radius); 
       cv::circle(src,cv::Point(center),static_cast<int> (radius),cv::Scalar(255,255,0),3,3); 
       mom= cv::moments(cv::Mat(contours[i])); 
      // draw mass center 
      cv::circle(result, 
      // position of mass center converted to integer 
       cv::Point(mom.m10/mom.m00,mom.m01/mom.m00), 
      2,cv::Scalar(0,0,255),2);// draw black dot 
       break; 

case 3: // should be a triangle 
       poly.clear(); 
        cv::approxPolyDP(cv::Mat(contours[i]),poly, 
        5, // accuracy of the approximation 
        true); // yes it is a closed shape 
        // Iterate over each segment and draw it 
        itp= poly.begin(); 
       while (itp!=(poly.end()-1)) { 
        cv::line(src,*itp,*(itp+1),cv::Scalar(0,255,255),2); 
        ++itp; 
        } 
       // last point linked to first point 
       cv::line(src,*(poly.begin()),*(poly.end()-1),cv::Scalar(100,255,100),2); 
       mom= cv::moments(cv::Mat(contours[i])); 
       // draw mass center 
       cv::circle(result, 
       // position of mass center converted to integer 
       cv::Point(mom.m10/mom.m00,mom.m01/mom.m00), 
       2,cv::Scalar(0,0,255),2);// draw black dot 
        break; 
      case 5 :// should be a pentagon 
       poly.clear(); 
        cv::approxPolyDP(cv::Mat(contours[i]),poly, 
        5, // accuracy of the approximation 
        true); // yes it is a closed shape 
       // Iterate over each segment and draw it 
       itp= poly.begin(); 
       while (itp!=(poly.end()-1)) { 
        cv::line(src,*itp,*(itp+1),cv::Scalar(0,0,255),2); 
        ++itp; 
       } 
       // last point linked to first point 
        cv::line(src,*(poly.begin()),*(poly.end()-1),cv::Scalar(255,0,0),2); 
        mom= cv::moments(cv::Mat(contours[i])); 
      // draw mass center 
      cv::circle(result, 
      // position of mass center converted to integer 
       cv::Point(mom.m10/mom.m00,mom.m01/mom.m00), 
      2,cv::Scalar(0,0,255),2);// draw black dot 
        break; 

      default : 
       contours[i].clear(); 
     } 
// iterate over all contours 
     int j = 0; 
     for(int i = 0; i < contours.size();i++) { 
      if (!contours[i].empty()){ 
      // compute all moments 

      j++; // At the end j should be 3 
    } 
      if(j ==3){ 
     cv::drawContours(result,contours,-1, // draw all contours 
      cv::Scalar(0), // in black 
      2); // with a thickness of 2 
     cv::imshow("result",result); 
      } 
} std::cout<<j<<std::endl; 


    return j; 
} 

Toute idée comment résoudre ce problème? merci!

+1

Peut-être pourriez-vous combiner votre approche avec un détecteur d'angle (qui fait également partie d'opencv) et l'ajouter comme deuxième étape à votre classificateur? (c'est-à-dire seulement passer des formes qui ont 0, 3 ou 5 coins) – jmetz

+1

Alternativement, une approche plus générale serait d'utiliser une approche de classificateur en cascade, qui exige que vous entraîniez le classificateur avec des échantillons positifs et négatifs jusqu'à ce que le niveau désiré de discrimination soit atteint . – jmetz

+0

@mutzmatron merci pour votre réponse, je ne peux pas essayer la deuxième suggestion parce que je travaille avec le résultat dans d'autres classes, mais le premier sonne bien, mais pour faire cela? merci d'avance – Engine

Répondre

0

Si les formes géométriques sont toujours situés dans un tel motif en damier et les formes ont même taille et de l'orientation dans ce modèle tout le temps, je:

  1. détecter le motif en damier.
  2. supprimer la distorsion en perspective d'une échelle homographie
  3. et tourner de telle sorte que le motif en damier est aligné axe et à une adaptation d'échelle chanfrein d'utilisation
  4. donné pour détecter les formes spécifiées.
Questions connexes