使用cv2.findContours的输出作为plt.contour的输入。
使用cv2.findContours的输出作为plt.contour的输入。
我有以下图片
我使用以下代码找到轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) contour = contours[0]
然后,我确定轮廓的中心
def find_center(contour: np.ndarray) -> tuple: M = cv2.moments(contour) x = int(M["m10"] / M["m00"]) y = int(M["m01"] / M["m00"]) return x, y
我想在一个网格中显示轮廓,其中中心
表示原点/(0,0)点。所以,我将轮廓
的每个xy点的中心
相减。
接下来,我想使用这些新的坐标作为plt.contour
的输入。
我需要创建一个网格
xs = new_contour[:,:,0].flatten() ys = new_contour[:,:,1].flatten() x = np.arange(int(min(xs)), int(max(xs)), 1) y = np.arange(int(min(ys)), int(max(ys)), 1) X, Y = np.meshgrid(x, y)
如何定义/处理Z
,使输出开始看起来像这样:
编辑
如建议所示,我尝试使用patch.Polygon
。
p = Polygon(np.reshape(new_contour, (-1, 2)), facecolor = 'k', closed=True) fig, ax = plt.subplots() ax.add_patch(p) ax.set_xlim([-250, 250]) ax.set_ylim([-250, 250]) plt.show()
输出如下:
它开始看起来像这样,但仍然旋转。我不确定为什么。当我检查文档时,每个函数都使用xy坐标,所以不是这个问题。我做错了什么?
问题的出现原因:
问题出现在使用cv2.findContours输出作为plt.contour输入时,由于OpenCV和Matplotlib的坐标系方向不同,导致绘图结果不符合预期。
解决方法:
为了解决这个问题,需要对坐标进行转换。根据代码中给出的例子,可以通过以下方式解决:
1. 首先,计算轮廓的中心点坐标(x, y)。通过cv2.moments函数计算轮廓的矩,然后利用中心矩计算中心点坐标。
2. 将每个轮廓点的x坐标减去中心点的x坐标,得到转换后的x坐标列表xs。
3. 将每个轮廓点的y坐标减去中心点的y坐标,并取相反数,得到转换后的y坐标列表ys。
4. 使用plt.plot函数绘制曲线,传入转换后的x坐标列表xs和y坐标列表ys作为输入。
5. 在绘制曲线之前,调用plt.grid函数添加网格线。
6. 最后调用plt.show函数显示绘图结果。
除了上述方法,如果需要绘制封闭的多边形,可以使用matplotlib的Polygon函数和patches模块。具体步骤如下:
1. 根据上述步骤计算中心点坐标(x, y)。
2. 使用Polygon函数创建多边形对象p,传入一个由转换后的轮廓点坐标组成的列表作为参数,设置closed参数为True。
3. 创建一个绘图对象fig和一个子图对象ax。
4. 在子图对象ax上调用add_patch方法,将多边形对象p添加到图形中。
5. 使用ax.set_xlim和ax.set_ylim方法设置x轴和y轴的范围,以确保多边形在图中显示完整。
6. 在绘制多边形之前,调用plt.grid函数添加网格线。
7. 最后调用plt.show函数显示绘图结果。
通过对OpenCV和Matplotlib的坐标系进行转换,可以解决使用cv2.findContours输出作为plt.contour输入时导致绘图结果不符合预期的问题。同时,根据需要绘制的图形类型选择合适的绘图函数和参数,以确保绘图结果符合预期。