Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

approxPolyDP can't do what you are looking for! check the doc or Douglas-Peucker algorithm

You can use convexHull image description

vector<cv::Point> hull;
cv::convexHull(contours[i], hull);
//draw it
cv::polylines(im, hull, true, cv::Scalar(255, 0, 0));

or approx it a bit more image description

double len = arcLength(hull, true);
double epsilon = 0.02*len;
vector<cv::Point> approx;
cv::approxPolyDP(hull, approx, epsilon, true);
cv::polylines(im, approx, true, cv::Scalar(0, 255, 0));

Or minAreaRect image description

cv::RotatedRect rr;
rr = cv::minAreaRect(contours[i]);
//draw the rectangle
cv::Point2f rect_points[4];
rr.points(rect_points);
for (int j = 0; j < 4; j++)
    cv::line(im, rect_points[j], rect_points[(j + 1) % 4], cv::Scalar(0, 0, 255), 2, 8);

OR look at find square example: https://github.com/Itseez/opencv/blob/master/samples/python2/squares.py

approxPolyDP can't do what you are looking for! for becase you have to find right epsilon that cuts just "defects", check the doc or Douglas-Peucker algorithm

You can use convexHull image description

vector<cv::Point> hull;
cv::convexHull(contours[i], hull);
//draw it
cv::polylines(im, hull, true, cv::Scalar(255, 0, 0));

or approx it a bit more image description

double len = arcLength(hull, true);
double epsilon = 0.02*len;
vector<cv::Point> approx;
cv::approxPolyDP(hull, approx, epsilon, true);
cv::polylines(im, approx, true, cv::Scalar(0, 255, 0));

Or minAreaRect image description

cv::RotatedRect rr;
rr = cv::minAreaRect(contours[i]);
//draw the rectangle
cv::Point2f rect_points[4];
rr.points(rect_points);
for (int j = 0; j < 4; j++)
    cv::line(im, rect_points[j], rect_points[(j + 1) % 4], cv::Scalar(0, 0, 255), 2, 8);

OR look at find square example: https://github.com/Itseez/opencv/blob/master/samples/python2/squares.py