You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从matplotlib.pyplot绘制的图像中提取像素坐标为二元组列表

问题描述

我正在编写Python图像处理程序,需从原始图像生成ROI图像。希望用户可按左上到右下逻辑手动输入ROI点坐标,或在matplotlib.pyplot显示的原始图像上通过两次左键点击获取坐标(仅聚焦鼠标点击坐标提取功能)。我找到一个普通绘图中存储点击点坐标的方案,但不适用于图像绘图,尝试编写的代码里.mpl_connect和.mpl_disconnect方法无法与plt.imshow配合使用。期望实现针对图像的该功能:图像以矩阵形式加载,提取的像素坐标为像素的行列索引,浮点坐标需转为整数。

原尝试代码:

# import the necessary packages
import cv2 as cv
import matplotlib.pyplot as plt

image="..\Esercizi_da_consegnare\Avanzato\aaa\DSCF0336.jpg"

# Simple mouse click function to store coordinates
def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    x_int=int(ix)
    y_int=int(iy)

    # print 'x = %d, y = %d'%( 
    #     ix, iy)

    # assign global variable to access outside of function
    global coords
    coords.append((x_int,y_int))
    

    # Disconnect after 2 clicks
    if len(coords) == 2:
        image.mpl_disconnect(cid)
        plt.close(1)
    return

cv.imread(image, cv.IMREAD_GRAYSCALE)
plt.imshow(image, cmap="gray")
plt.show()

coords = []

# Call click func
cid = image.mpl_connect('button_press_event', onclick)

plt.show()
print(coords)
解决方案

原代码核心问题

  • cv.imread的结果未赋值给变量,image仍是字符串路径,不存在.mpl_connect方法
  • 事件绑定、图像显示顺序错误,需先绑定事件再显示图像
  • 断开事件的对象错误,应使用绘图的figure对象而非图像矩阵

修正后的代码

import cv2 as cv
import matplotlib.pyplot as plt

# 用原始字符串处理路径,避免转义问题
image_path = r"..\Esercizi_da_consegnare\Avanzato\aaa\DSCF0336.jpg"
# 加载灰度图像
image = cv.imread(image_path, cv.IMREAD_GRAYSCALE)

# 存储点击坐标的列表
coords = []

def onclick(event):
    # 仅处理左键点击且点击位置在图像区域内
    if event.button == 1 and event.inaxes is not None:
        # xdata对应图像列索引,ydata对应行索引,转为整数
        x_coord = int(round(event.xdata))
        y_coord = int(round(event.ydata))
        coords.append((x_coord, y_coord))
        print(f"已选择坐标: ({x_coord}, {y_coord})")
        
        # 收集到2个点后断开事件并关闭窗口
        if len(coords) == 2:
            plt.disconnect(cid)
            plt.close()

# 创建绘图窗口并显示图像
fig, ax = plt.subplots()
ax.imshow(image, cmap="gray")

# 绑定鼠标点击事件到画布
cid = fig.canvas.mpl_connect('button_press_event', onclick)

# 显示图像并等待点击
plt.show()

# 输出最终结果
if len(coords) == 2:
    print(f"最终ROI坐标: 左上{coords[0]}, 右下{coords[1]}")
else:
    print("未选择足够的坐标")

代码说明

  • 使用原始字符串r""处理文件路径,避免转义字符引发的路径错误
  • 确保cv.imread的结果赋值给image,得到图像矩阵
  • 事件绑定的对象是fig.canvas(绘图画布),而非图像本身
  • 增加有效性判断:只响应左键点击,且点击位置在图像显示区域内
  • 坐标转换用round更精准,xdata对应图像的列索引(水平方向),ydata对应行索引(垂直方向),符合像素矩阵的行列逻辑

内容的提问来源于stack exchange,提问作者Marco_Mosca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:10:37