是否有任何辅助方法可以绘制由cv2.minAreaRect()返回的旋转矩形,大概为((x1,y1),(x2,y2),angle)
? cv2.rectangle()不支持角度。
由于返回的元组不是“RotatedRect”类(因为它似乎没有在Python绑定中实现),因此没有points()
方法,如C ++教程"Creating Bounding rotated boxes and ellipses for contours¶"所示。
如何从直线绘制旋转的矩形 - 围绕中心点或给定的第一个点旋转?
答案 0 :(得分:47)
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)
应该这样做。
来源:
1)http://opencvpython.blogspot.in/2012/06/contours-2-brotherhood.html
答案 1 :(得分:2)
这是绘制旋转矩形的具体示例。这个想法是使用Otsu's threshold获得二进制图像,然后使用cv2.findContours
找到轮廓。我们可以使用cv2.minAreaRect
获得旋转的矩形,并使用cv2.boxPoints
获得四个角顶点。要绘制矩形,我们可以使用cv2.drawContours
或cv2.polylines
。
输入->
输出
代码
import cv2
import numpy as np
# Load image, convert to grayscale, Otsu's threshold for binary image
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Find contours, find rotated rectangle, obtain four verticies, and draw
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
rect = cv2.minAreaRect(cnts[0])
box = np.int0(cv2.boxPoints(rect))
cv2.drawContours(image, [box], 0, (36,255,12), 3) # OR
# cv2.polylines(image, [box], True, (36,255,12), 3)
cv2.imshow('image', image)
cv2.waitKey()
答案 2 :(得分:1)
我知道这是很久以前问过的,但是我想分享一种与公认答案所建议的方法不同的方法,也许这可能对其他人有所帮助(实际上这是在C ++中完成的,但似乎python仍然缺少RotatedRect类)。
这个想法是从角度,大小(W和H)和起始点定义一个旋转的矩形。此初始点是相对的左上角(相同大小的矩形的左上角,没有旋转角度)。从这里可以获得四个顶点,这使我们可以用四条线绘制旋转的矩形。
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)
我想,可以使用类似的方法来定义旋转矩形的中心,而不是相对的左上角初始点,但是我还没有尝试过。
答案 3 :(得分:1)
扩展 Tobias Hermann 的回答:如果您没有轮廓,而是由其中心点、尺寸和角度定义的旋转矩形:
import cv2
import numpy as np
# given your rotated rectangle is defined by variables used below
rect = ((center_x, center_y), (dim_x, dim_y), angle)
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)
答案 4 :(得分:0)
基于@ smajtks的答案,我根据其中心而不是其相对的左上起始点定义了旋转的矩形。这是代码:
class RRect_center:
def __init__(self, p0, s, ang):
(self.W, self.H) = s # rectangle width and height
self.d = math.sqrt(self.W**2 + self.H**2)/2.0 # distance from center to vertices
self.c = (int(p0[0]+self.W/2.0),int(p0[1]+self.H/2.0)) # center point coordinates
self.ang = ang # rotation angle
self.alpha = math.radians(self.ang) # rotation angle in radians
self.beta = math.atan2(self.H, self.W) # angle between d and horizontal axis
# Center Rotated vertices in image frame
self.P0 = (int(self.c[0] - self.d * math.cos(self.beta - self.alpha)), int(self.c[1] - self.d * math.sin(self.beta-self.alpha)))
self.P1 = (int(self.c[0] - self.d * math.cos(self.beta + self.alpha)), int(self.c[1] + self.d * math.sin(self.beta+self.alpha)))
self.P2 = (int(self.c[0] + self.d * math.cos(self.beta - self.alpha)), int(self.c[1] + self.d * math.sin(self.beta-self.alpha)))
self.P3 = (int(self.c[0] + self.d * math.cos(self.beta + self.alpha)), int(self.c[1] - self.d * math.sin(self.beta+self.alpha)))
self.verts = [self.P0,self.P1,self.P2,self.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_center(P0,(W,H),ang)
rr.draw(image)
cv2.imshow("Text Detection", image)
cv2.waitKey(200
在这里,矩形围绕其中心旋转,而不是从起始点P0开始旋转。