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;`
As you can see from the picture, 3 rectangles are detected. However, I want to detect all 5 rectangles. How do I achieve that?
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.
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.
Just use findContours() in your image, then decide whether the contour is closed or not by examining the hierarchy passed to the findContours() function.
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.
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
approxPolyDP for contours
You may also want to try threshold to find the edges, instead of Canny.
threshold (gray, bw, 0, 255, THRESH_BINARY|THRESH_OTSU);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With