OpenCV - Detect hand-drawing shapes

前端 未结 1 580
北恋
北恋 2020-12-14 13:31

Could OpenCV detect the geometric shapes which is drawn by hand as below? The shape can be a rectangle, triangle, circle, curve, arc,polygon,... I am going to develop an and

相关标签:
1条回答
  • 2020-12-14 13:58

    Well, I tried it in a harry. Normally you need to skeletonize the input. Anyway. You can reason about the shapes based on their points. Normally a square has 4, a triangle 3, etc. Effort results:

    Canny results: enter image description here

    Polygonal approximation: enter image description here

    Console output:

    contour points:11
    contour points:6
    contour points:4 
    contour points:5
    

    Here is the code:

        Mat src=imread("WyoKM.png");
        Mat src_gray(src.size(),CV_8UC1);
        if (src.empty()) exit(-10);
        imshow("img",src);
    
        /// Convert image to gray and blur it
        cvtColor( src, src_gray, CV_BGR2GRAY );
        threshold(src_gray,src_gray,100,255,src_gray.type());
        imshow("img2",src_gray);
    
        Mat canny_output;
        vector<vector<Point> > contours;
        vector<Vec4i> hierarchy;
    
        /// Detect edges using canny
        int thresh=100;
        Canny( src_gray, canny_output, thresh, thresh*2, 3 );
        imshow("canny",canny_output);
        imwrite("canny.jpg",canny_output);
    
        /// Find contours
        findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    
        // testing the approximate polygon
        cv::Mat result(src_gray.size(),CV_8U,cv::Scalar(255));
        for(int i=0;i<contours.size();i=i+4) //for testing reasons. Skeletonize input.
        {
            std::vector<cv::Point> poly;
            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
            std::vector<cv::Point>::const_iterator itp= poly.begin();
            cout<<"\ncontour points:"<<poly.size();
            while (itp!=(poly.end()-1)) {
                cv::line(result,*itp,*(itp+1),cv::Scalar(0),2);
                ++itp;
            }
            // last point linked to first point
            cv::line(result,
                *(poly.begin()),
                *(poly.end()-1),cv::Scalar(20),2);
        }
    
        imshow("result",result);
        imwrite("results.jpg",result);
    
        cvWaitKey();
    
    0 讨论(0)
提交回复
热议问题