Ask Your Question

Contour Approximation OpenCV

asked 2015-11-27 08:28:23 -0500

arp1561_ans gravatar image

updated 2015-11-27 12:00:34 -0500

pklab gravatar image

I am using opencv for python. For a bad shape, we use approxpolyDP().For this, I created a bad rectangle(added to the post)

While using this, I only get 2 dots and not a proper rectangle.

Can anyone help me why this is happening?

import cv2
import numpy as np

im = cv2.imread("badrect.png")
img = im
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(img,100,200)

(_,cnts,_) = cv2.findContours(canny,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

cnt = cnts[0]

epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)



This is how the output comes out as

This is how the output comes out as

This is my desired result This is my desired result!

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2015-11-27 11:56:58 -0500

pklab gravatar image

updated 2015-11-28 02:59:53 -0500

approxPolyDP can't do what you are looking 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];
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:

edit flag offensive delete link more


I still dont get a line around the rectangle

import cv2
import numpy as np

im = cv2.imread("badrect.png")
img = im
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY)

(_,cnts,_) = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

cnt = cnts[1]
hull = cv2.convexHull(cnt)


Here -> This is how it looks

If you could help me, that would be great since i am stuck here for a very long time

arp1561_ans gravatar imagearp1561_ans ( 2015-11-28 00:25:56 -0500 )edit

@arp1561_ans please you are using 2 answer for same issue. Use just one !

ConvexHull solve your problem check your code with suggested tutorial. Drawing Functions in OpenCV, Contours - 1: Getting Started , Contours - 2 : Brotherhood, Contours in OpenCV

pklab gravatar imagepklab ( 2015-11-28 03:08:23 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2015-11-27 08:28:23 -0500

Seen: 3,771 times

Last updated: Nov 28 '15