Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV Python: Draw minAreaRect ( RotatedRect not implemented)

Tags:

python

opencv

Are there any helper methods to draw a rotated rectangle that is returned by cv2.minAreaRect() presumably as ((x1,y1),(x2,y2),angle)? cv2.rectangle() does not support an angle. And since the tuple returned is not of the "RotatedRect" class (because it seems to not be implemented in the Python bindings) there is no points() method, as shown in the C++ tutorial "Creating Bounding rotated boxes and ellipses for contours¶".

How could a rotated rectangle be drawn from lines - rotate about the center point or the first point given?

like image 250
handle Avatar asked Aug 13 '13 10:08

handle


2 Answers

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

like image 93
Tobias Hermann Avatar answered Sep 19 '22 05:09

Tobias Hermann


I know this was asked long ago, but I would like to share a different approach as the one proposed by the accepted answer, maybe this could be helpful for someone else (actually this has been done before in C++, but it seems python still lacks of RotatedRect class).

The idea is to define a rotated rectangle from an angle, a size (W and H) and an initial point. This initial point is the relative top-left corner (the top-left corner of the same size rectangle with no rotation angle). From here, the four vertices can be obtained, which allows us to draw the rotated rectangle with four lines.

class RRect:   def __init__(self, p0, s, ang):     self.p0 = (int(p0[0]),int(p0[1]))     (self.W, self.H) = s     self.ang = ang     self.p1,self.p2,self.p3 = self.get_verts(p0,s[0],s[1],ang)     self.verts = [self.p0,self.p1,self.p2,self.p3]    def get_verts(self, p0, W, H, ang):     sin = numpy.sin(ang/180*3.14159)     cos = numpy.cos(ang/180*3.14159)     P1 = (int(self.H*sin)+p0[0],int(self.H*cos)+p0[1])     P2 = (int(self.W*cos)+P1[0],int(-self.W*sin)+P1[1])     P3 = (int(self.W*cos)+p0[0],int(-self.W*sin)+p0[1])     return [P1,P2,P3]    def draw(self, image):     print(self.verts)     for i in range(len(self.verts)-1):       cv2.line(image, (self.verts[i][0], self.verts[i][1]), (self.verts[i+1][0],self.verts[i+1][1]), (0,255,0), 2)     cv2.line(image, (self.verts[3][0], self.verts[3][1]), (self.verts[0][0], self.verts[0][1]), (0,255,0), 2)  (W, H) = (30,60) ang = 35 #degrees P0 = (50,50) rr = RRect(P0,(W,H),ang) rr.draw(image) cv2.imshow("Text Detection", image) cv2.waitKey(200) 

I guess, a similar approach can be used to define the rotated rectangle in terms of its center instead of its relative top-left initial point, but I haven't tried it yet.

like image 38
smajtkst Avatar answered Sep 19 '22 05:09

smajtkst