Draw solid rotated rectangle using openCV python

Question: Given the four vertices p1(x1, y1), p2(x2, y2), p3(x3, y3), p4(x4, y4) or the center point (cx, cy), (w, h) of the rotated rectangle ), θ draw a rotated solid matrix: output a numpy array, the values ​​in the rectangle are all 255

To see the method, just go to the bottom
To see the method, go to the bottom
To see the method, go to the bottom

1. The formulas for obtaining the four vertices through the center point, width, height, and angle are available online. Finally, the x and y coordinates of the four vertices are output.

import numpy as np

rectangle = [cx,cy,w,h,θ]

x1 = int(np.cos(rectangle[4])*(-rectangle[2]/2) - np.sin(rectangle[4])*(-rectangle[3]/2) + rectangle[0])
x2 = int(np.cos(rectangle[4])*(rectangle[2]/2) - np.sin(rectangle[4])*(-rectangle[3]/2) + rectangle[0])
x3 = int(np.cos(rectangle[4])*(-rectangle[2]/2) - np.sin(rectangle[4])*(rectangle[3]/2) + rectangle[0])
x4 = int(np.cos(rectangle[4])*(rectangle[2]/2) - np.sin(rectangle[4])*(rectangle[3]/2) + rectangle[0])
y1 = int(np.sin(rectangle[4])*(-rectangle[2]/2) + np.cos(rectangle[4])*(-rectangle[3]/2) + rectangle[1])
y2 = int(np.sin(rectangle[4])*(rectangle[2]/2) + np.cos(rectangle[4])*(-rectangle[3]/2) + rectangle[1])
y3 = int(np.sin(rectangle[4])*(-rectangle[2]/2) + np.cos(rectangle[4])*(rectangle[3]/2) + rectangle[1])
y4 = int(np.sin(rectangle[4])*(rectangle[2]/2) + np.cos(rectangle[4])*(rectangle[3]/2) + rectangle[1])

2. Draw a solid rectangle

Regarding how to draw a solid rectangle, because openCV’s own cv2.rectangle can only draw a rectangle with an angle of 0, there is no way to use it, so at first I planned to traverse each point to determine whether it is within the rectangle to draw it.

from shapely import geometry

def ifPointsInside(polygon, Points):
    line = geometry.LineString(polygon)
    point = geometry.Point(Points)
    polygon = geometry.Polygon(line)
    return polygon.contains(point)

And use concave and convex polygons to judge, and compare the areas of four triangles and rectangles to find
Insert image description here

As a result, every point needs to be traversed and calculated. I used it to process deep learning data. There are more than 10,000 pictures with a resolution of 640*480, which is more than 3 billion times. Before he finished traversing, I left first. , too slow

Then I thought: first use cv2.line to draw the border, and then traverse the image horizontally to find the 255 value inside. If two 255s are found, mark all the ones in the middle with 255. It succeeded, but it is still slow.

The final solution: Use cv2.line to draw line by line, from (x1, y1)->(x2, y2) to (x3, y3)->(x4, y4)

Output = np.zeros((480,640,1)) 
#我的用单通道,三通道就把1改成3,下面的(255)改成(255,255,255)

a = (y3-y1)/(x3-x1)
#这个是用来计算斜率

for x in range(0,abs(x3-x1)):
    cv2.line(Output,(int(x1+x),int(y1+a*x)),(int(x2+x),int(y2+a*x)), (255), 2)

Draw according to 1pixel, the accuracy is not enough, change to 0.01 step

Output = np.zeros((480,640,1)) 

a = (y3-y1)/(x3-x1)

for x in range(0,100*abs(x3-x1)):
    cv2.line(Output,(int(x1+x/100),int(y1+a*x/100)),(int(x2+x/100),int(y2+a*x/100)), (255), 2)

Drawn
Insert image description here

(23/09/09) Then I found out that opencv has a function, which really made me cry:

bbox=[[x1,y1],[x2,y2],[x3,y3],[x4,y4],...]
image = cv2.fillPoly(image, [np.array(bbox)], color)

Guess you like

Origin blog.csdn.net/qq_34029469/article/details/120539122