I have an OpenCV contour c
which is close to a quadrilateral in its shape, but it can have 4 to multiple of dozens of points.
I want to find the quadrilateral q
which is the closest to the contour c
(one way could be to minimize the area of the difference between them).
I currently use
q = cv2.approxPolyDP(c, 0.02 * cv2.arcLength(c, True), closed=True)
but the result is not always a quadrilateral. I have already tried techniques like those in cv2.approxPolyDP() , cv2.arcLength() How these works and in How to force approxPolyDP() to return only the best 4 corners? - Opencv 2.4.2 (binary search for example), but it doesn't always yield a quadrilateral.
Is there another way (probably with something else than approxPolyDP
?) to find the best quadrilateral approximation to a contour?
Note: another linked question is Crop image based on largest quadrilateral contour OpenCV but it does not give a solution to this problem.
I recently had a similar problem, but instead of approximating a contour with a general quadrilateral, I tried to approximate it with a rectangle. I hope that my solution would be helpful to your problem as well.
I used the cv.minAreaRect method. This method finds the enclosing Rotated Rectangle
of a set of points with minimal area.
In python opencv, a Rotated Rectangle
is built out of (center_x, center_y), (width, height), angle_in_degrees
. I suggest you to check this link to avoid confusion about the returned angle_in_degrees
value, and for more useful information regarding "minAreaRect" method.
Here is a simple usage example of the "minAreaRect" method:
import cv2
def check_rectangle_approx(contour):
rectangle = cv2.minAreaRect(contour)
(center_x, center_y), (width, height), angle = rectangle
return width * height - cv2.contourArea(contour) < SOME_THERSHOLD_VLAUE
In my case, where I had close to rectangle contours, minAreaRect()
returned decent approximations. Hope it will be the same for you.
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