Opencv Python: Draw Minarearect ( Rotatedrect Not Implemented)

OpenCV Python: Draw minAreaRect ( RotatedRect not implemented)

rect = cv2.minAreaRect(cnt)
box = cv2.cv.BoxPoints(rect) # cv2.boxPoints(rect) for OpenCV 3.x
box = np.int0(box)
cv2.drawContours(im,[box],0,(0,0,255),2)

should do the trick.

sources:

1) http://opencvpython.blogspot.in/2012/06/contours-2-brotherhood.html

2) Python OpenCV Box2D

OpenCV's RotatedRect has no attribute 'size' in Python3. How to work around this?

According to this tutorial, minAreaRect returns a rectangle with ((center_x,center_y),(width,height),angle). Thus, if you modify your expand_minRect to recreate it with the correct components, it should work.

def expand_minRect(self, value):
self.minRect = (self.minRect[0], # keep the center
(self.minRect[1][0] + value, self.minRect[1][1] + value), # update the size
self.minRect[2]) # keep the angle

Note: The problem emerges from the fact that OpenCV python has a less object-oriented implementation than OpenCV c++. It does not return a struct which enables accessing each attribute by name (like ".size"). You need to know the tuple order and assumptions for each element.

cv2 minAreaRect center rotated by 90 degrees?

You are using np.column_stack(np.where(thresh > 0)) to find the contours.
OpenCV uses (x, y) notation whereas NumPy uses (row, col).
You can check it by printing coords.

I suggest using OpenCV functions where possible.
The following code works.

coords, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = cv2.minAreaRect(np.vstack(coords))

See Contour Features.

OpenCV - minAreaRect // points is not a numerical tuple

cv2.findContours returns a list of contours. Each contour is a list of points. Therefore contours returned by it is not a list of points, but rather a list of lists of points.

cv2.minAreaRect on the other hand requires as input a single list of points, and therefore you get an error when you feed it with contours.

You can solve it by flattening the contours into a single list of points, like this:

contours_flat = np.vstack(contours).squeeze()
minArea = cv2.minAreaRect(contours_flat)

Altenatively you can get the minAreaRect for each contour in contours list by using (idx is the 0 based index of the contour):

minArea = cv2.minAreaRect(contours[idx])

You can see here more about contours: Contours, cv::findContours

And about minAreaRect: cv::minAreaRect

What is the output of minAreaRect(contours)

You are correct. Having a look at OpenCV's (C++) documentation on cv::minAreaRect, we see that a cv::RotatedRect is returned. The full construcor of cv::RotatedRect is:

cv::RotatedRect::RotatedRect(const cv::Point2f& center, const cv::Size2f& size, float angle)    

The description of the corresponding parameters is:

center    The rectangle mass center.
size Width and height of the rectangle.
angle The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.

Obviously, center and size are treated as tuples in the Python API, and all three parameters are returned as a tuple also. So, all in all this fits quite well your assumption.

Hope that helps!

OpenCV's RotatedRect angle does not provide enough information

After learning from Sebastian Schmitz and Michael Burdinov answers this is how I solved it:

RotatedRect rotated_rect = minAreaRect(contour);
float blob_angle_deg = rotated_rect.angle;
if (rotated_rect.size.width < rotated_rect.size.height) {
blob_angle_deg = 90 + blob_angle_deg;
}
Mat mapMatrix = getRotationMatrix2D(center, blob_angle_deg, 1.0);

So, in fact, RotatedRect's angle does not provide enough information for knowing an object's angle, you must also use RotatedRect's size.width and size.height.



Related Topics



Leave a reply



Submit