c++ - Extracting geometric forms with opencv -


i running video in want detect 3 geometric forms triangle circle , pentagon, , nothing else, here frame video , result :

source

the correct result

correct result

one bad result many.

bad result

and here's 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 ); ( 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 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 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 triangle                  poly.clear();                     cv::approxpolydp(cv::mat(contours[i]),poly,                     5, // accuracy of approximation                     true); // yes closed shape                     // iterate on each segment , draw                     itp= poly.begin();                 while (itp!=(poly.end()-1)) {                     cv::line(src,*itp,*(itp+1),cv::scalar(0,255,255),2);                     ++itp;                     }                 // last point linked 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 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 pentagon                 poly.clear();                      cv::approxpolydp(cv::mat(contours[i]),poly,                     5, // accuracy of approximation                     true); // yes closed shape                 // iterate on each segment , draw                 itp= poly.begin();                 while (itp!=(poly.end()-1)) {                     cv::line(src,*itp,*(itp+1),cv::scalar(0,0,255),2);                     ++itp;                 }                 // last point linked 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 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 on contours         int j = 0;         for( int = 0; < contours.size();i++) {             if ( !contours[i].empty()){             // compute moments              j++; // @ end  j should 3      }             if(j ==3 ){         cv::drawcontours(result,contours,-1, // draw contours              cv::scalar(0), // in black             2); // thickness of 2         cv::imshow("result",result);             } }   std::cout<<j<<std::endl;       return j; } 

any idea how solve ? thanks!

if geometric shapes located within such checkerboard pattern , shapes have same size , orientation within pattern time, would:

  1. detect checkerboard pattern.
  2. remove perspective distortion homography
  3. scale , rotate checkerboard pattern axis aligned , @ given scale
  4. use chamfer matching detect specified shapes.

Comments