坐标未对齐:如何使用 matplotlib 在 cv2 检测到的边缘上进行绘图?

问题描述 投票:0回答:1

我有一个名为“rect2.png”的 252x252 二进制图像,如下所示:

rect2.png

我的目标是检测图像中白色圆圈的边缘,然后根据边缘像素进行数学运算。 我运行以下代码来加载图像、获取边缘并显示结果。

# Load the image
img = cv2.imread('rect2.png')

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# detect edges
edges = cv2.Canny(gray, 100, 200)

# show the result
f, ax = plt.subplots()
ax.set_xlim([0,edges.shape[0]])
ax.set_ylim([0,edges.shape[1]])
ax.imshow(edges, cmap='gray', origin='lower')

生成的边缘看起来正确:

图像:检测到边缘

然后我找到边缘中的非零像素:

# find nonzero pixels i.e. those which create the edge
nzx, nzy = np.nonzero(edges)

# loop through the indices and scatter the points over the imshowed edges
for x,y in zip(nzx,nzy):
    ax.scatter(nzx, nzy, s=1, color='orange')

生成的斧头如下:

图像:原始边缘(白色)加上分散为点的非零索引(橙色)

您知道这里的问题是什么吗?我如何确保索引与图像对齐?

我尝试按照散点图点和图像像素之间的映射中所述转换坐标,但这显示了不需要的结果:

xraw = nzx[180] # arbitrarily chosen position
yraw = nzy[180] # arbitrarily chosen position

# transform according to the link above
x,y = ax.transData.inverted().transform([xraw,252-yraw]) # 252 is the height of the image

# show raw coordinate
ax.scatter(xraw,yraw,s=100,color='lightblue')

# show transformed coordinate
ax.scatter(x,y,s=100,color='yellow')

图像:原始坐标(浅蓝色)按预期覆盖 matplotlib 点。新坐标(黄色)完全指向别处

此外,我尝试将

origin='lower'
更改为
origin='upper'
但没有任何变化。另外,我尝试使用此处描述的
extent
kwarg Matplotlib imshow offset to match axis? 如下:

ax.imshow(edges, cmap='gray', origin='lower', extent=[0, 252, 0, 252])

没有变化。我觉得我犯了一些非常明显的错误,但我看不到它。将不胜感激任何帮助!

opencv matplotlib coordinates indices edges
1个回答
0
投票

解决了。

与cv2无关。此处找到的解决方案:与 plt.scatter 相比,为什么 plt.imshow 翻转坐标?

# imshow transposed edges
ax.imshow(edges.transpose(), cmap='gray', origin='lower', extent=[0, 252, 0, 252])

# invert the yaxis
ax.invert_yaxis()
© www.soinside.com 2019 - 2024. All rights reserved.