7

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?

donjuedo
  • 2,475
  • 18
  • 28
Rougher
  • 834
  • 5
  • 19
  • 46
  • 1
    I don't understand what your question is. And usually it is not your English but how you think about your problem. Just look at your question and think how you would solve the question if you are a person answering. – Tae-Sung Shin Apr 08 '14 at 17:57
  • My question is how to detect polygon contours that I drawed by using opencv? – Rougher Apr 08 '14 at 19:32
  • In attached pictures I used functions from opencv, but instead 5 expected rectangles I got only 3. – Rougher Apr 08 '14 at 19:37
  • 3
    What are "Angle" and "SetLable" in your code? They are shown as cannot be identified – Samitha Chathuranga Mar 16 '15 at 19:21

2 Answers2

10

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

Haris
  • 13,645
  • 12
  • 90
  • 121
1

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

threshold (gray, bw, 0, 255, THRESH_BINARY|THRESH_OTSU);