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::findContoursAnd 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
How to Use Python-Docx to Replace Text in a Word Document and Save
"Permission Denied" Trying to Run Python on Windows 10
What Is the Purpose of Meshgrid in Python/Numpy
Define CSS Class in Django Forms
Representing and Solving a Maze Given an Image
Should I Be Adding the Django Migration Files in the .Gitignore File
Cheap Way to Search a Large Text File for a String
Mapping a Range of Values to Another
Does 'Anaconda' Create a Separate Pythonpath Variable for Each New Environment
Filename and Line Number of Python Script
Pandas - Add New Column to Dataframe from Dictionary
Plotting Results of Hierarchical Clustering Ontop of a Matrix of Data in Python
Pandas - Filter Dataframe by Another Dataframe by Row Elements
How to Strip All Whitespace from String
Python [Errno 98] Address Already in Use