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

Rougher picture Rougher · Apr 8, 2014 · Viewed 13k times · Source

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?

Answer

Haris picture Haris · Apr 9, 2014

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