注意: AO⊥BE !!!
∠GAF = ∠FBG = ∠GCH = ∠HDK = ∠KEG = 36°
∠GOF = ∠FOG = ∠GOH = ∠HOK = ∠KOG = 360° / 5 = 72°
∠AOX = 90°
∠GOF = 72°
∠FOB = 36°
∠BOX = 90° - 72° = 18°
∠GOX = ∠KOX = 36° - 18° = 18°
∠COX = ∠DOX = 36° + 18° = 54°
∠FOX = 36° + 18° = 54°
假设 OA = r !!!
因为:
∠BOX = 90° - 72° = 18°
∠FOA = 36°
OB = r
所以:
pi_val = np.pi / 180
OF * np.cos(36 * pi_val) = OB * np.sin(18 * pi_val)
OF = min_r = (r * np.sin(18 * pi_val)) / np.cos(36 * pi_val)
# 外五边形的坐标
A(0,r)
B(r * np.cos(18 * pi_val), r * np.sin(18 * pi_val))
C(r * np.cos(54 * pi_val), - r * np.sin(54 * pi_val))
D(- r * np.cos(54 * pi_val), - r * np.sin(54 * pi_val))
E(- r * np.cos(18 * pi_val), r * np.sin(18 * pi_val))
# 内五边形的坐标
F(min_r * np.cos(54 * pi_val),min_r * np.sin(54 * pi_val))
G(min_r * np.cos(18 * pi_val),- min_r * np.sin(18 * pi_val))
H(0, - min_r)
K(- min_r * np.cos(18 * pi_val),- min_r * np.sin(18 * pi_val))
G(- min_r * np.cos(54 * pi_val),min_r * np.sin(54 * pi_val))
import cv2 as cv
import numpy as np
# 使用 **arrowedLine** 箭头线创建坐标系
def create_coordinate(mat):
h,w,c = mat.shape
half_h = int(h / 2)
half_w = int(w / 2)
# 绘制x轴
ptsx1 = (10, half_h)
ptsx2 = (w - 10, half_h)
cv.arrowedLine(mat,ptsx1,ptsx2,(0,0,0),tipLength=0.03)
cv.putText(mat,'x',(w - 25, half_h + 25), cv.FONT_HERSHEY_SIMPLEX, 1, (0,0,0))
# 绘制y轴
ptsy1 = (half_w, h - 10)
ptsy2 = (half_w, 10)
cv.arrowedLine(mat,ptsy1,ptsy2,(0,0,0),tipLength=0.03)
cv.putText(mat,'y',(half_w + 10, 25), cv.FONT_HERSHEY_SIMPLEX, 1, (0,0,0))
# 绘制原点和坐标
cv.putText(mat,'O(0,0)',(half_w, half_h - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
return mat
# 以五角星的重心为原点,计算各点坐标
def get_star_point(r = 100):
# 计算没一份的度数和内五边形的r
pi_val = np.pi / 180
min_r = r * np.sin(18 * pi_val) / np.cos(36 * pi_val)
# 外五边形的坐标
a = [0,r]
b = [r * np.cos(18 * pi_val), r * np.sin(18 * pi_val)]
c = [r * np.cos(54 * pi_val), - r * np.sin(54 * pi_val)]
d = [- r * np.cos(54 * pi_val), - r * np.sin(54 * pi_val)]
e = [- r * np.cos(18 * pi_val), r * np.sin(18 * pi_val)]
# 内五边形的坐标
in_a = [min_r * np.cos(54 * pi_val),min_r * np.sin(54 * pi_val)]
in_b = [min_r * np.cos(18 * pi_val),- min_r * np.sin(18 * pi_val)]
in_c = [0, - min_r]
in_d = [- min_r * np.cos(18 * pi_val),- min_r * np.sin(18 * pi_val)]
in_e = [- min_r * np.cos(54 * pi_val),min_r * np.sin(54 * pi_val)]
return {
"out": [a, b, c, d, e],
"in": [in_a, in_b, in_c, in_d, in_e]
}
def tagging_points(img):
# 获取五角星各个坐标点
points = get_star_point()
# 获取内外五边形的各点坐标
[a,b,c,d,e] = list(map(lambda items: [int(items[0]),-int(items[1])], points.get("out")))
[in_a,in_b,in_c,in_d,in_e] = list(map(lambda items: [int(items[0]),-int(items[1])], points.get("in")))
cv.putText(img,f'A',(a[0] + 200, a[1] + 200), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'B',(b[0] + 200, b[1] + 200 - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'C',(c[0] + 200, c[1] + 200 + 10), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'D',(d[0] + 200, d[1] + 200 + 10), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'E',(e[0] + 200, e[1] + 200 - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'F',(in_a[0] + 200, in_a[1] + 200 - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'G',(in_b[0] + 200, in_b[1] + 200 - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'H',(in_c[0] + 200, in_c[1] + 200 - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'K',(in_d[0] + 200, in_d[1] + 200 - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
cv.putText(img,f'G',(in_e[0] + 200, in_e[1] + 200 - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0))
return img
# 绘制五角星
def create_star(img):
# 获取五角星各个坐标点
points = get_star_point()
# 获取内外五边形的各点坐标
[a,b,c,d,e] = list(map(lambda items: [int(items[0]),-int(items[1])], points.get("out")))
[in_a,in_b,in_c,in_d,in_e] = list(map(lambda items: [int(items[0]),-int(items[1])], points.get("in")))
# 设置原点坐标
o = [0,0]
# 设置多边形点
pts = np.array([o,a,in_a,o,in_a,b,o,b,in_b,o,in_b,c,o,c,in_c,o,in_c,d,o,d,in_d,o,in_d,e,o,e,in_e,o,in_e,a,o])
# 由于图片宽度400,设置原点(200,200)
pts[:,:] += 200
cv.polylines(img, [pts], True, (0,0,0),1)
return img
def create_demo():
img = np.ones((400,400,3),np.uint8)*255
# 绘制坐标系
img = create_coordinate(img)
# 绘制五角星
img = create_star(img)
# 标注各点
img = tagging_points(img)
cv.imshow("coordinate", img)
cv.waitKey(0)
cv.destroyAllWindows()
if __name__ == "__main__":
create_demo()