matplotlib imshow()和像素强度

时间:2015-05-18 11:27:37

标签: python matplotlib plot

我试图了解输入到matplotlib的imshow()函数的矩阵的值如何确定灰度模式下像素的强度。考虑示例代码:

import random
import matplotlib.pyplot as plt
import matplotlib.cm as cm

def pixels(n=3):
    pixel_data = []
    for _ in range(n):
        row = []
        for _ in range(n):
            row.append(random.randint(1, 10))
        pixel_data.append(row)
    return pixel_data

if __name__ == '__main__':
    pixel_data = pixels()
    print(pixel_data)
    plt.imshow(pixel_data, origin='lower', cmap=cm.Greys_r)
    plt.show()

这里的pixel_data是3 * 3"矩阵":

[[7, 4, 6], [7, 7, 6], [4, 7, 9]]

这里的值如何确定我在图像中看到的灰色阴影?

2 个答案:

答案 0 :(得分:11)

只是一个简单的例子:

import numpy as np
data = array([[7, 4, 6], [7, 7, 6], [4, 7, 9]])
imshow(data, 'gray', origin='lower')

enter image description here

Matplotlib的imshow有3个控制每个像素灰度的参数:

  1. vmin:设置图像的最小强度值(灰度中的黑色),默认情况下设置为图像数组的最小值。
  2. vmax:设置图像的最大强度值(灰度为白色),默认设置为数组的最大值。
  3. 如果要查看真实的灰度图像,则需要手动设置vmin=0vmax=255(对于8位灰度图像)。或者将数组重新调整为[0,255]。

    1. interpolation:默认设置为bilinear interpolation,如果图片尺寸大于或小于图片矩阵的尺寸,则会控制插值像素的值。
    2. 这是因为关闭插值会发生什么结果:

      imshow(data, 'gray', origin='lower', interpolation='none')
      

      enter image description here

      这是vminvmax参数功能的一个示例:

      imshow(data, 'gray', origin='lower', interpolation='none', vmin=0, vmax=20)
      

      enter image description here

      有关双线性插值或插值方法的更多信息,请参阅维基百科或:

      http://matplotlib.org/examples/images_contours_and_fields/interpolation_methods.html

      其中none = nearest反映了没有插值的原始4x4数组。

      编辑:基本上,当您想象图像时有两个关键因素:

      1. 图片的原始尺寸
      2. 图像可视化的大小
      3. 如果以上两种尺寸相同,则图像以其原始尺寸可视化,完全没有问题,但是,这在现实世界中很少发生。想象一下,一个简单的例子,两个人在不同分辨率的两个显示器(假设相同型号)中寻找相同的图像:一个是1280x768,另一个是800x600。显示器实际上具有相同的尺寸,在两种情况下图像都是相同的,但是,两个显示器中的像素密度不同(第一个像素每英寸的像素数多于第二个),因此, 800x600显示器将寻找更大(质量更差)的画面。

        情况不一样,但matplotlib会发生类似情况。默认情况下,Matplotlib未经过优化,无法以原始大小显示图像。实际上,如果您显示3x3矩阵,您甚至无法看到它(太小),但默认情况下,matplotlib会显示一个(比方说256x256)大的类似平滑的图像(第一张图像)上文)。

        这一切背后发生了什么? figure&n; figsizedpi参数控制输出图像的大小和像素密度。如果没有手动给出,matplotlib将默认尝试估计。

        因此,无论是通过手动指定还是默认创建,您的3x3矩阵最终都会得到256x256像素。如上所述,vminvmax控制颜色的最小值和最大值(在这种情况下为灰度,因此vmin = blackvmax = white)。

        那么,如何确定每个像素的值?这取决于所使用的插值方法。首先,您的矩阵(在这种情况下为3x3)点沿着图像的大小(例如256x256)均匀分布。然后,使用插值方法估计新图像的其余点(256x256):

        • 无插值:像素获取矩阵中最接近元素的值

        • 双线性插值:像素得到一个在矩阵最近的4个邻居内平均的值

        还有更多......有关详细信息,请参阅上面的插值方法。

        例如,请查看wikipedia中的以下图片:

        enter image description here

        想象一下,带有颜色的点是来自矩阵的数据,黑点代表当您使图像大小大于矩阵大小时需要估算的像素之一。在图像的特定情况下,使用双线性插值来估计黑点(对于新图像)的值。如您所见,像素的值设置为围绕该像素的矩阵中点的加权平均值。如果插值方法设置为“没有”'或者'最近的'在matplotlib中,黑点的值仅由黄色像素给出(它最接近一个)。

        在这里查看有关插值的更多信息: http://www.cambridgeincolour.com/tutorials/image-interpolation.htm

        此外,请查看here以了解复杂实际上是如何使用matplotlib以原始像素大小显示图像。

答案 1 :(得分:0)

颜色映射过程(适用于来自ColorMappable的子类,而不仅仅是AxesImageimshow创建的))是一个两步过程。

  1. 转换数据空间' - > [0,1](Normalize及其子类实例)
  2. map [0,1] - > RGB(Colormap个实例)。
  3. 可用的规范类是:

    所有颜色贴图实例都有一个__call__方法,可以从[0,1] - >进行映射。 RGB。

    imshow公开vminvmaxnormcmap的kwargs。如果未指定,则使用Normalize(线性)实例。如果您未指定vminvmax(或将其设置为None),vminvmax将设置为输入数据的最小值/最大值。如果您未指定cmap,则(遗憾地)默认为'jet'