Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I detect polygon contours that I drew by using opencv?

I'm new to OpenCV. I know that many ways exist for detecting contours of polygons. But, how do I detect polygon contours that I drew using opencv?

Here is my code:

Mat src = imread("C:/Users/Nickolay/Desktop/1.jpg");
resize(src, src, Size(400, 400), 0, 0, INTER_CUBIC);
if (src.empty()) 
{
    cout << "Cannot load image!" << endl;
    return -1;
}

//================================

Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
Mat bw;
Canny(gray, bw, 800, 850, 5, true);
imshow("canny", bw);
vector<vector<Point>> countours;
findContours(bw.clone(), countours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

vector<Point> approx;
Mat dst = src.clone();

for(int i = 0; i < countours.size(); i++)
{
    approxPolyDP(Mat(countours[i]), approx, arcLength(Mat(countours[i]), true) * 0.01, true);

    if (approx.size() >= 4 && (approx.size() <= 6))
    {
        int vtc = approx.size();
        vector<double> cos;
        for(int j = 2; j < vtc + 1; j++)
            cos.push_back(Angle(approx[j%vtc], approx[j-2], approx[j-1]));

        sort(cos.begin(), cos.end());

        double mincos = cos.front();
        double maxcos = cos.back();

        if (vtc == 4)// && mincos >= -0.5 && maxcos <= 0.5)
        {
            Rect r = boundingRect(countours[i]);
            double ratio = abs(1 - (double)r.width / r.height);

            line(dst, approx.at(0), approx.at(1), cvScalar(0,0,255),4);
            line(dst, approx.at(1), approx.at(2), cvScalar(0,0,255),4);
            line(dst, approx.at(2), approx.at(3), cvScalar(0,0,255),4);
            line(dst, approx.at(3), approx.at(0), cvScalar(0,0,255),4);
            SetLabel(dst, "RECT", countours[i]);
        }
    }
}

//================================

imshow("source", src);
imshow("detected lines", dst);

waitKey(0);

return 0;`

Example

As you can see from the picture, 3 rectangles are detected. However, I want to detect all 5 rectangles. How do I achieve that?

like image 816
Rougher Avatar asked Apr 08 '14 17:04

Rougher


People also ask

How does OpenCV detect contours?

Contour Detection using OpenCV (Python/C++) Using contour detection, we can detect the borders of objects, and localize them easily in an image. It is often the first step for many interesting applications, such as image-foreground extraction, simple-image segmentation, detection and recognition.

What algorithm is used to detect polygons OpenCV?

Contours – convex contours and the Douglas-Peucker algorithm The first facility OpenCV offers to calculate the approximate bounding polygon of a shape is cv2. approxPolyDP.

How does OpenCV detect closed contours?

Just use findContours() in your image, then decide whether the contour is closed or not by examining the hierarchy passed to the findContours() function.

What function is used to detect polygon?

Approach : The approach we would be used to detect the shape of a given polygon will be based on classifying the detected shape on the basis of a number of sides it has.


2 Answers

The problem may be you are directly passing edge image for find contour, which may contain many unconnected edges.

So before find contour apply Morphology Transformations.

like,

   Size kernalSize (5,5);
   Mat element = getStructuringElement (MORPH_RECT, kernalSize, Point(1,1)  );
   morphologyEx( bw, bw, MORPH_CLOSE, element );

See the result.

Bounding rectangle for contours

bounding rectangle for  contours

approxPolyDP for contours

approxPolyDP for  contours

like image 91
Haris Avatar answered Oct 06 '22 13:10

Haris


You may also want to try threshold to find the edges, instead of Canny.

threshold (gray, bw, 0, 255, THRESH_BINARY|THRESH_OTSU);
like image 32
user2277773 Avatar answered Oct 06 '22 11:10

user2277773