Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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

threshold (gray, bw, 0, 255, THRESH_BINARY|THRESH_OTSU);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top