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

时间:2014-12-30 11:19:53

标签: python image image-processing matplotlib scikit-image

简短版本:是否有用于显示图像的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值仍然不是整数。

imshow包中的spectral方法做得更好:

import spectral as spc
spc.imshow(im)

然后在右下方我现在有pixel=[103,152]

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

  1. 来自imshow的{​​{1}}(和来自matplotlib的{​​{1}})是否可以强制显示正确的(整数)像素索引?
  2. 是否可以扩展这些方法中的任何一种以显示像素值?

5 个答案:

答案 0 :(得分:38)

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

你可以修补ax.format_coord,类似于this official example。我将在这里使用稍微更加“pythonic”的方法,它不依赖于全局变量。 (请注意,我假设没有指定extent kwarg,类似于matplotlib示例。要完全通用,您需要执行a touch more work。)

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()

enter image description here

或者,只需插入我自己的一个项目,就可以使用mpldatacursor。如果您指定hover=True,只要您将鼠标悬停在已启用的艺术家上,该框就会弹出。 (默认情况下,它仅在单击时弹出。)请注意mpldatacursor确实正确处理extentorigin kwargs到imshow

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()

enter image description here

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

使用mpldatacursor,您可以使用自定义格式化程序指定它们。 ij参数是正确的像素索引,无论绘制的图像的extentorigin如何。

例如(请注意图片的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()

enter image description here

答案 1 :(得分:2)

绝对简单的"单线"要做到这一点:(不依赖于datacursor

def val_shower(im):
    return lambda x,y: '%dx%d = %d' % (x,y,im[int(y+.5),int(x+.5)])

plt.imshow(image)
plt.gca().format_coord = val_shower(ims)

它将图像置于关闭状态,因此请确保如果您有多个图像,则每个图像都会显示其自己的值。

答案 2 :(得分:0)

我看到的所有示例只有在x和y范围从0开始时才有效。以下是使用图像范围查找z值的代码。

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

d = np.array([[i+j for i in range(-5, 6)] for j in range(-5, 6)])
im = ax.imshow(d)
im.set_extent((-5, 5, -5, 5))

def format_coord(x, y):
    """Format the x and y string display."""
    imgs = ax.get_images()
    if len(imgs) > 0:
        for img in imgs:
            try:
                array = img.get_array()
                extent = img.get_extent()

                # Get the x and y index spacing
                x_space = np.linspace(extent[0], extent[1], array.shape[1])
                y_space = np.linspace(extent[3], extent[2], array.shape[0])

                # Find the closest index
                x_idx= (np.abs(x_space - x)).argmin()
                y_idx= (np.abs(y_space - y)).argmin()

                # Grab z
                z = array[y_idx, x_idx]
                return 'x={:1.4f}, y={:1.4f}, z={:1.4f}'.format(x, y, z)
            except (TypeError, ValueError):
                pass
        return 'x={:1.4f}, y={:1.4f}, z={:1.4f}'.format(x, y, 0)
    return 'x={:1.4f}, y={:1.4f}'.format(x, y)
# end format_coord

ax.format_coord = format_coord

如果你正在使用PySide / PyQT,这里有一个鼠标悬停工具提示数据的例子

import matplotlib
matplotlib.use("Qt4Agg")
matplotlib.rcParams["backend.qt4"] = "PySide"
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

# Mouse tooltip
from PySide import QtGui, QtCore
mouse_tooltip = QtGui.QLabel()
mouse_tooltip.setFrameShape(QtGui.QFrame.StyledPanel)
mouse_tooltip.setWindowFlags(QtCore.Qt.ToolTip)
mouse_tooltip.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
mouse_tooltip.show()

def show_tooltip(msg):
    msg = msg.replace(', ', '\n')
    mouse_tooltip.setText(msg)

    pos = QtGui.QCursor.pos()
    mouse_tooltip.move(pos.x()+20, pos.y()+15)
    mouse_tooltip.adjustSize()
fig.canvas.toolbar.message.connect(show_tooltip)


# Show the plot
plt.show()

答案 3 :(得分:0)

使用Jupyter,您可以使用datacursor(myax)ax.format_coord

示例代码:

%matplotlib nbagg

import numpy as np  
import matplotlib.pyplot as plt

X = 10*np.random.rand(5,3)

fig,ax = plt.subplots()    
myax = ax.imshow(X, cmap=cm.jet,interpolation='nearest')
ax.set_title('hover over the image')

datacursor(myax)

plt.show()

datacursor(myax)也可以替换为ax.format_coord = lambda x,y : "x=%g y=%g" % (x, y)

答案 4 :(得分:-1)

要获取图像的交互式像素信息,请使用模块imagetoolbox 要下载该模块,请打开命令提示符并编写

  

pip install imagetoolbox   编写给定的代码以获取图像的交互式像素信息   enter image description here   输出:enter image description here