2013-07-19 38 views
0

我跑中,我想检测3种几何形状的三角形圆,五边形,而不是其他的视频几何形状,在这里从这个视频中的帧,结果我得到:提取与OpenCV的

source

正确的结果从许多

correct result

一个坏的结果。

Bad result

,这里是我的代码:

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; 
} 

不知道如何解决这个问题? 谢谢!

+1

也许你可以结合你的方法与角探测器(也是opencv的一部分),并将其作为第二阶段添加到你的分类器? (即只传递具有0,3或5个角的形状) – jmetz

+1

或者,更一般的方法是使用级联分类器方法,该方法要求您用正样本和负样本训练分类器,直到达到所需的歧视水平。 – jmetz

+0

@mutzmatron感谢您的回答,我不能尝试第二个建议,因为我在其他类中的结果工作,但第一个听起来不错,但要做到这一点?在此先感谢 – Engine

回答

0

如果几何形状总是位于这样的棋盘图案内和形状有图案中相同的大小和方向的时候,我想:

  1. 检测棋盘图案。
  2. 除去透视失真的单应性
  3. 缩放和旋转,使得棋盘图案轴线对齐,并且在给定的规模
  4. 使用倒角匹配来检测指定的形状。