From my experiments, the angle returned by RotatedRect\'s angle variable goes from -90 to 0 degrees, which is not sufficient to determine if the object is leaned to the left
This is what I use (c
is my contour). Basically, I get the longest line's du and dv, and then use atan2()
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
origin = box[0]
rect_width, rect_height = rect[1]
if rect_width > rect_height:
target = box[3]
else:
target = box[1]
dv = target[1] - origin[1]
du = target[0] - origin[0]
angle_rads = math.atan2(dv, du)
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
.
Switching values of width and height of rectangle is the same as rotating it by 90 degrees. So if the range of angles was 180 degrees instead of 90 than same rectangle would have 2 representations (width, height, angle) and (height, width, angle+90). Having range of 90 degrees you can represent every rectangle and you can do that in only one way.
I explained how you can convert the angle of the rectangle into [0-180] in this thread.
The Angle is always calculated along the longer side.