如何从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
相关产品推荐
相关产品推荐

