0

我运行一个视频,我想在其中检测 3 个几何形状三角形圆和五边形,仅此而已,这里是该视频的一帧以及我得到的结果:

资源

正确的结果

正确的结果

许多人的一个坏结果。

结果不好

这是我的代码:

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

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

4

1 回答 1

0

如果几何形状始终位于这样的棋盘图案中,并且形状在该图案中始终具有相同的大小和方向,我会:

  1. 检测棋盘图案。
  2. 用单应性去除透视失真
  3. 缩放和旋转,以使棋盘图案轴对齐并以给定的比例
  4. 使用倒角匹配来检测指定的形状。
于 2013-12-16T09:55:26.527 回答