【问题标题】:python - RGB matrix of an imagepython - 图像的 RGB 矩阵
【发布时间】:2020-11-14 12:58:20
【问题描述】:

以图像为输入,如何得到对应的rgb矩阵? 我检查了 numpy.asarray 函数。这会给我rgb矩阵还是其他矩阵?

【问题讨论】:

    标签: python image numpy python-imaging-library


    【解决方案1】:

    请注意,截至 2018 年,此答案已过时; scipy 已弃用 imread,您应该切换到 imageio.imread。有关两者之间的差异,请参阅this transition doc。如果您只是导入新库来代替旧库,下面的代码应该可以正常工作,但我还没有测试过。


    最简单的答案是在 PIL 周围使用 NumPy 和 SciPy 包装器。有a great tutorial,但基本思路是:

    from scipy import misc
    arr = misc.imread('lena.png') # 640x480x3 array
    arr[20, 30] # 3-vector for a pixel
    arr[20, 30, 1] # green value for a pixel
    

    对于 640x480 RGB 图像,这将为您提供 uint8 的 640x480x3 数组。

    或者你可以只用 PIL(或者更确切地说是 Pillow;如果你还在使用 PIL,这可能不起作用,或者可能很慢)打开文件,然后直接将它传递给 NumPy:

    import numpy as np
    from PIL import Image
    img = Image.open('lena.png')
    arr = np.array(img) # 640x480x4 array
    arr[20, 30] # 4-vector, just like above
    

    这将为您提供uint8 类型的 640x480x4 数组(第 4 个是 alpha;PIL 始终将 PNG 文件加载为 RGBA,即使它们没有透明度;如果您不确定,请参阅 img.getbands())。

    如果你根本不想使用 NumPy,PIL 自己的 PixelArray 类型是一个更有限的数组:

    arr = img.load()
    arr[20, 30] # tuple of 4 ints
    

    这将为您提供一个 640x480 PixelAccess RGBA 4 元组数组。

    或者您也可以在图片上拨打getpixel

    img.getpixel(20, 30) # tuple of 4 ints
    

    【讨论】:

    • 更新:imread 在 SciPy 1.0.0 中已弃用,并将在 1.2.0 中删除。请改用imageio.imreadsource
    • @HarshitKumar 感谢您的更新;我会将其编辑为答案。既然这已经五年了,还有什么应该更新的吗?
    【解决方案2】:

    我有一种感觉,我没有完全按照您的意愿行事,所以请说明这是否完全关闭。您可以像这样打开图像并获得一个像素数组:

    import Image
    im = Image.open('Lenna.png')
    pixels = list(im.getdata())
    

    这将为您提供一个 RGB 数据的平面列表,看起来像

    [(226, 137, 125), (226, 137, 125), (223, 137, 133), (223, 136, 128), 
     (226, 138, 120), (226, 129, 116), (228, 138, 123), (227, 134, 124), 
     (227, 140, 127), (225, 136, 119), (228, 135, 126), (225, 134, 121),...
    

    现在这将是平面数组中的所有像素,如果您想要一个二维数组,则需要一些额外的代码。不确定PIL中是否有直接的功能。

    【讨论】:

    • 是的,这确实是我想要的!只是一个问题,在这个列表中,像素是按图像的水平遍历还是垂直遍历的顺序排列的?还是这个数据没有顺序?
    • @Ojas:正如Image.getdata 的文档所说,“第一行的值紧跟在零行的值之后,依此类推。”但是,这不是最好的方法。
    • @Bemmu 很抱歉回复您的旧帖子。但是,我认为您可能可以提供帮助:) 我怎样才能获得具有(m, n) 尺寸的 RGB 图像的 numpy 数组?例如,两个 64X64 像素 RGB 图像应生成一个(2, 12288) 数组。提前谢谢!
    【解决方案3】:

    我尝试了imageio.imread 并且效果很好,但一分钟后偶然发现matplotlib 中的一个函数完全相同,得到一个numpy n x m x 3 数组:

    from matplotlib import pyplot as plt
    image = plt.imread(path)
    

    【讨论】:

      【解决方案4】:

      您可以使用Pillow 做到这一点,getdata 方法会为您提供一个像素的平面数组,然后您可以使用图像的size 构建一个矩阵。

      from PIL import Image
      
      def getPixels(filename):
          img = Image.open(filename, 'r')
          w, h = img.size
          pix = list(img.getdata())
          return [pix[n:n+w] for n in range(0, w*h, w)]
      

      【讨论】:

      • 我必须删除 'r' 参数才能打开才能使其正常工作。
      • 显然它是 mode 参数的默认值,所以谁知道^^
      【解决方案5】:

      如果您或其他任何人正在使用 opencv,还要添加。

       imgc=cv2.imread(file)
      

      或以灰度方式读取

       imgc=cv2.imread(file,0)
      

      如果您要在图像之间进行一些比较,您可能需要考虑将像素数组转换为直方图以标准化数据。

         hist = np.histogram(img.flatten(),256,[0,256])[0]
      

      上面的行首先将您的 img 数组展平,因此您确实会丢失图像的维度。然后它产生从 0 到 256 的 bin(对于灰度图像),并将 img 中的计数添加到这些 bin 中,并将它们作为 hist 返回,然后可以绘制出来。例如,如果 100 bin 的值为 20,则表示图像中 20 个像素的值为 100。

      希望这为希望开始使用 opencv 的人或任何人提供了另一种思考的可能性。

      【讨论】:

        猜你喜欢
        • 2014-05-11
        • 2021-06-13
        • 2020-01-31
        • 1970-01-01
        • 2017-04-16
        • 1970-01-01
        • 1970-01-01
        • 2015-02-20
        • 1970-01-01
        相关资源
        最近更新 更多