1. 知识点
- 学习 cv.polylines 函数的使用;
- 学习 cv.fillPoly 函数的使用。
2. 绘制折线或多边形 cv.polylines 函数说明
2.1 函数使用
代码语言:javascript复制cv.polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]]) → img
2.2 参数说明
参数 | 说明 |
---|---|
img | 表示要在其上绘制矩形的图像的img对象。 |
pts | 表示一个或多个点集。 |
isClosed | 表示标志,决定所绘制的多边形是否闭合。若为 True ,则画若干个闭合多边形;若为 False ,则画一条连接所有点的折线。 |
color | 表示颜色。 |
thickness | 表示线宽,注意:必须大于0。 |
lineType | 表示绘制直线的线性,默认为 LINE_8。 |
shift | 表示坐标精确到小数点后第几位。 |
2.3 lineType 值说明
值 | 描述 |
---|---|
cv.LINE_4 | 表示 4 邻接线型。 |
cv.LINE_8 | 表示 8 邻接线型。 |
cv.LINE_AA | 表示抗锯齿线型,图像更平滑。 |
3. 填充颜色 cv.fillPoly 函数说明
3.1 函数使用
代码语言:javascript复制cv.fillPoly(img, pts, color[, lineType[, shift[, offset]]]) → img
3.2 参数说明
参数 | 说明 |
---|---|
img | 表示要在其上绘制矩形的图像的img对象。 |
pts | 表示一个或多个点集。 |
color | 表示颜色。 |
lineType | 表示绘制直线的线性,默认为 LINE_8。 |
shift | 表示坐标精确到小数点后第几位。 |
3.3 lineType 值说明
值 | 描述 |
---|---|
cv.LINE_4 | 表示 4 邻接线型。 |
cv.LINE_8 | 表示 8 邻接线型。 |
cv.LINE_AA | 表示抗锯齿线型,图像更平滑。 |
4. 注意
- thickness 线宽的值必须大于0;
- isClosed 闭合标志为 True 时绘制若干个闭合多边形;闭合标志为 False 时绘制一条连接所有点的折线;
- pts 点集表示函数 cv.polylines 与 cv.fillPoly 可以绘制或填充一个或多个多边形;
- pts 点集参数必须设置dtype=np.uint8。
5. 实例
5.1 实例代码
代码语言:javascript复制import cv2 as cv
import numpy as np
# 以五角星的重心为原点,计算各点坐标
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 create_pentagon(a,b,c,d,e,isClosed=True,color=(0,0,255),fill=False,fillColor=(255,0,0)):
img = np.ones((200, 200, 3), np.uint8)*255
pts = np.array([a,b,c,d,e])
# 向左上角移动100像素原点
pts[:,:] = 100
cv.polylines(img, [pts], isClosed, color,1)
# 判断是否填充多边形
if fill:
cv.fillPoly(img,[pts],fillColor)
return img
def create_five_pointed_star(a,b,c,d,e,
isClosed=True,
color=(0,0,255),
fill=False,
fillColor=(255,0,0)):
img = np.ones((200, 200, 3), np.uint8)*255
pts = np.array([a,c,e,b,d])
# 向左上角移动100像素原点
pts[:,:] = 100
cv.polylines(img, [pts], isClosed, color,1)
# 判断是否填充多边形
if fill:
cv.fillPoly(img,[pts],fillColor)
return img
def create_five_pointed_star_all(
a,b,c,d,e,
in_a,in_b,in_c,in_d,in_e,
isClosed=True,
color=(0,0,255),
fill=False,
fillColor=(255,0,0)):
img = np.ones((200, 200, 3), np.uint8)*255
pts = np.array([a,in_a,b,in_b,c,in_c,d,in_d,e,in_e])
# 向左上角移动100像素原点
pts[:,:] = 100
cv.polylines(img, [pts], isClosed, color,1)
# 判断是否填充多边形
if fill:
cv.fillPoly(img,[pts],fillColor)
return img
def create_demo():
# 以五角星长轴半径计算各点坐标,注意计算坐标需要倒转
star_points = get_star_point(60)
[a,b,c,d,e] = list(map(lambda items: list(map(lambda val: - int(val), items)), star_points.get("out")))
[in_a, in_b, in_c, in_d, in_e] = list(map(lambda items: list(map(lambda val: - int(val), items)), star_points.get("in")))
#
img = np.ones((600, 600, 3), np.uint8)*255
# 不闭合折线
# 五角星【线交叉】
img[0:200,0:200] = create_five_pointed_star(a,b,c,d,e,isClosed=False)
# 五边形
img[200:400,0:200] = create_pentagon(a,b,c,d,e,isClosed=False)
# 五角星【十点】
img[400:600,0:200] = create_five_pointed_star_all(a,b,c,d,e,in_a,in_b,in_c,in_d,in_e,isClosed=False)
# 闭合多边形
# 五角星【线交叉】
img[0:200,200:400] = create_five_pointed_star(a,b,c,d,e)
# 五边形
img[200:400,200:400] = create_pentagon(a,b,c,d,e)
# 五角星【十点】
img[400:600,200:400] = create_five_pointed_star_all(a,b,c,d,e,in_a,in_b,in_c,in_d,in_e)
# # 闭合填充多边形
# # 五角星【线交叉】
img[0:200,400:600] = create_five_pointed_star(a,b,c,d,e,fill=True)
# 五边形
img[200:400,400:600] = create_pentagon(a,b,c,d,e,fill=True)
# 五角星【十点】
img[400:600,400:600] = create_five_pointed_star_all(a,b,c,d,e,in_a,in_b,in_c,in_d,in_e,fill=True)
cv.imshow("img", img)
cv.waitKey(0)
cv.destroyAllWindows()
if __name__ == "__main__":
create_demo()
5.2 实例运行结果
6. 总结
- 由于计算五角星各点坐标时,采用的时数学的四象限坐标,以重心为原点,创建坐标;
- opencv 绘制图形时,x轴和数学坐标轴一样,但是y是以向下为正轴,同时坐标原点在图像的左上角[0,0]位置;
- 通过以上两点,可以知道第一:需要将计算的y轴坐标取反;第二:需要将计算点的原点进行位移计算。