Python中图像的交互式像素信息?

新手上路,请多包涵

简短版本: 是否有用于显示实时显示像素索引和强度的图像的 Python 方法?因此,当我将光标移到图像上时,我会不断更新显示,例如 pixel[103,214] = 198 (用于灰度)或 pixel[103,214] = (138,24,211) 用于 rgb?

长版:

假设我打开一个保存为 ndarray im 的灰度图像,并使用来自 matplotlib 的 imshow 显示它:

 im = plt.imread('image.png')
plt.imshow(im,cm.gray)

我得到的是图像,在窗口框架的右下角,是像素索引的交互式显示。除了它们不完全一样,因为值不是整数:例如 x=134.64 y=129.169

如果我将显示器设置为正确的分辨率:

 plt.axis('equal')

x 和 y 值仍然不是整数。

来自 spectral 包的 imshow 方法做得更好:

 import spectral as spc
spc.imshow(im)

然后在右下角,我现在有 pixel=[103,152] 例如。

然而,这些方法都没有显示像素值。所以我有两个问题:

  1. Can the imshow from matplotlib (and the imshow from scikit-image ) be coerced into showing the correct (integer) pixel indices?
  2. 这些方法中的任何一种都可以扩展以显示像素值吗?

原文由 Alasdair 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 520
1 个回答

有几种不同的方法可以解决这个问题。

你可以猴子补丁 ax.format_coord ,类似于 这个官方例子。我将在这里使用不依赖于全局变量的稍微更“pythonic”的方法。 (请注意,我假设没有指定 extent kwarg,类似于 matplotlib 示例。要完全通用,您需要做 更多的工作。)

 import numpy as np
import matplotlib.pyplot as plt

class Formatter(object):
    def __init__(self, im):
        self.im = im
    def __call__(self, x, y):
        z = self.im.get_array()[int(y), int(x)]
        return 'x={:.01f}, y={:.01f}, z={:.01f}'.format(x, y, z)

data = np.random.random((10,10))

fig, ax = plt.subplots()
im = ax.imshow(data, interpolation='none')
ax.format_coord = Formatter(im)
plt.show()

在此处输入图像描述

或者,只需插入我自己的项目之一,您可以为此使用 mpldatacursor 。如果您指定 hover=True ,只要您将鼠标悬停在启用的艺术家上方,就会弹出该框。 (By default it only pops up when clicked.) Note that mpldatacursor does handle the extent and origin kwargs to imshow correctly.

 import numpy as np
import matplotlib.pyplot as plt
import mpldatacursor

data = np.random.random((10,10))

fig, ax = plt.subplots()
ax.imshow(data, interpolation='none')

mpldatacursor.datacursor(hover=True, bbox=dict(alpha=1, fc='w'))
plt.show()

在此处输入图像描述

另外,我忘了提及如何显示像素索引。在第一个示例中,它只是假设 i, j = int(y), int(x) 。如果您愿意,可以添加它们来代替 xy

使用 mpldatacursor ,您可以使用自定义格式化程序指定它们。 The i and j arguments are the correct pixel indices, regardless of the extent and origin of the image plotted.

例如(注意图像的 extent 与显示的 i,j 坐标):

 import numpy as np
import matplotlib.pyplot as plt
import mpldatacursor

data = np.random.random((10,10))

fig, ax = plt.subplots()
ax.imshow(data, interpolation='none', extent=[0, 1.5*np.pi, 0, np.pi])

mpldatacursor.datacursor(hover=True, bbox=dict(alpha=1, fc='w'),
                         formatter='i, j = {i}, {j}\nz = {z:.02g}'.format)
plt.show()

在此处输入图像描述

原文由 Joe Kington 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题