Using bounding rectangle to get rotation angle not working (OpenCV/Python)

222 picture 222 · Mar 29, 2016 · Viewed 7.1k times · Source

I'm trying to straighten this letter but I'm not sure how to use the bounding rectangle to do so.

Here's what I have so far:

import cv2
import numpy as np

img = cv2.imread('rtes.jpg',0)

ret,thresh = cv2.threshold(img,127,255,0)
ret,contours,hierarchy = cv2.findContours(thresh, 1, 2)

cnt = contours[0]
M = cv2.moments(cnt)
print M
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
#cnt = contours[2]
#cv2.drawContours(img, [cnt], 0, (0,255,0), 3)
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img,[box],0,(255,0,0),2)
cv2.imshow('img',img)

k = cv2.waitKey(0)
if k == 27:         # wait for ESC key to exit
    cv2.destroyAllWindows()

and here's the result: enter image description here

I've looked into OpenCV docs to get it working but wasn't able to get it working. I'm trying to eventually write a loop that'll try 4 angles to see if it's straight.

Answer

s1hofmann picture s1hofmann · Mar 29, 2016
cv2.minAreaRect(cnt)

returns a Box2D object, which already stores rotation information.

(x,y),(width,height),theta

where theta is the angle enclosed by the horizontal and the first side of the Box2D object, in your example the shorter side of the inner contour.

It depends on what you're trying to achieve as an end result, but if you're only trying to rotate this particular example, you could do it this way:

rows, cols = img.shape
rect = cv2.minAreaRect(cnt)
center = rect[0]
angle = rect[2]
rot = cv2.getRotationMatrix2D(center, angle-90, 1)
print(rot)
img = cv2.warpAffine(img, rot, (rows,cols))