0.前言
关于多边形绘制函数cv2.polylines,它的第二个参数pts,用以表征所画多边形的顶点坐标,其数据类型可以是数组,也可以是列表。在网上看到有两种写法,如下:
写法一:
pts = np.array([[10,10],[100,10],[100,100],[10,100]],np.int32)
pts=pts.reshape((-1,1,2))
cv2.polylines(image,[pts],True,(255,0,0),5)
写法二:
pts = np.array([[10,10],[100,10],[100,100],[10,100]],np.int32)
pts=pts.reshape((1,-1,2))
cv2.polylines(image, pts,True,(255,0,0),5)
这两种写法都能绘出多边形,哪种更合理呢,那就要从pts为啥要用三维数组讲起了。
1. 三维数组的维度含义
在OpenCV中使用三维数组绘制多边形是为了支持多轮廓、多线段的灵活绘制需求。
三维数组的结构通常为 (num_contours, num_points_per_contour, 2),具体含义如下:
- 第一维 (num_contours):表示要绘制的轮廓(多边形/线段)的数量。
例如:绘制3个独立的轮廓(如3个矩形或3条线段)。 - 第二维 (num_points_per_contour):表示单个轮廓中的点的数量。
例如:一个矩形需要4个顶点,一条线段需要2个端点。 - 第三维 (2):表示每个点的二维坐标 (x, y)。
因此,即使只绘制一个多边形,也需要将其包裹成三维数组。例如:
pts = np.array([[10,10],[100,10],[100,100],[10,100]],np.int32)
pts=pts.reshape((1,-1,2))
cv2.polylines(image,pts,True,(255,0,0),5)
此处通过reshape(1, -1, 2),将原始二维数组转换为 (1,4,2),表示:
- 1个轮廓(多边形)
- 4个顶点
- 每个顶点是二维坐标。
如果需要绘制多个多边形,三维数组能直接支持批量操作:
pts = np.array([[10,10],[100,10],[100,100],[10,100],[30,30],[200,30],[200,200],[30,200]],np.int32)
pts=pts.reshape((2,-1,2))
cv2.polylines(image,pts,True,(255,0,0),5)
如上,写法二的数组各维度的物理意义是清晰的。
2. 写法一分析
pts = np.array([[10,10],[100,10],[100,100],[10,100]],np.int32)
pts=pts.reshape((-1,1,2))
cv2.polylines(image,[pts],True,(255,0,0),5)
这种写法的pts的维度为(4,1,2),每个点是作为一个独立的轮廓,故需要把[pts]作为参数。
如要绘制双轮廓,则可:
pts = np.array([[10,10],[100,10],[100,100],[10,100]],np.int32)
pts=pts.reshape((-1,1,2))
pts2 = np.array([[30,30],[200,30],[200,200],[30,200]],np.int32)
pts2=pts2.reshape((-1,1,2))
cv2.polylines(image,[pts,pts2],True,(255,0,0),5)
如上述,该写法虽然可行,但三维数组的各维度定义不清,不建议使用