简体   繁体   English

python - 图像的RGB矩阵

[英]python - RGB matrix of an image

Taking an image as input, how can I get the rgb matrix corresponding to it?以图像作为输入,如何得到与之对应的rgb矩阵? I checked out the numpy.asarray function.我检查了 numpy.asarray 函数。 Does that give me the rgb matrix or some other matrix?这是否给了我 rgb 矩阵或其他一些矩阵?

Note that this answer is outdated as of 2018;请注意,此答案截至 2018 年已过时; scipy has deprecated imread , and you should switch to imageio.imread . scipy已弃用imread ,您应该切换到imageio.imread See this transition doc about differences between the two.有关两者之间的差异,请参阅此转换文档 The code below should work with no changes if you just import the new library in place of the old, but I haven't tested it.如果您只是导入新库代替旧库,则下面的代码应该无需更改,但我尚未对其进行测试。


The simplest answer is to use the NumPy and SciPy wrappers around PIL.最简单的答案是使用围绕 PIL 的 NumPy 和 SciPy 包装器。 There's a great tutorial , but the basic idea is:一个很棒的教程,但基本思想是:

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

For a 640x480 RGB image, this will give you a 640x480x3 array of uint8 .对于 640x480 RGB 图像,这将为您提供uint8的 640x480x3 数组。

Or you can just open the file with PIL (or, rather, Pillow; if you're still using PIL, this may not work, or may be very slow) and pass it straight to NumPy:或者,您可以使用 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

This will give you a 640x480x4 array of type uint8 (the 4th is alpha; PIL always loads PNG files as RGBA, even if they have no transparency; see img.getbands() if you're every unsure).这将为您提供uint8类型的 640x480x4 数组(第 4 个是 alpha;PIL 始终将 PNG 文件加载为 RGBA,即使它们没有透明度;如果您不确定,请参阅img.getbands() )。

If you don't want to use NumPy at all, PIL's own PixelArray type is a more limited array:如果你根本不想使用 NumPy,PIL 自己的PixelArray类型是一个更有限的数组:

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

This gives you a 640x480 PixelAccess array of RGBA 4-tuples.这为您提供了一个 640x480 的 RGBA 4 元组PixelAccess阵列。

Or you can just call getpixel on the image:或者你可以在图像上调用getpixel

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

I have a feeling I'm not doing exactly what you wanted here, so please specify if this is totally off.我有一种感觉,我在这里没有完全按照您的意愿行事,因此请说明这是否完全关闭。 You could open the image like this and get an array of pixels:你可以像这样打开图像并获得一个像素数组:

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

This will get you a flat list of RGB data that looks like这将为您提供一个平面的 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),...

Now this will be all pixels in a flat array, if you want a two dimensional array then some additional code would be needed for that.现在这将是平面阵列中的所有像素,如果您想要二维阵列,则需要一些额外的代码。 Not sure if there is a direct function for it in PIL.不确定 PIL 中是否有直接的函数。

I tried imageio.imread and it worked great, but a minute later stumbled upon a function in matplotlib which worked exactly the same, getting a numpy n by m by 3 array:我尝试了imageio.imread并且它工作得很好,但一分钟后偶然发现了matplotlib中的一个函数,它的工作imageio.imread完全相同,得到了一个numpy n × m × 3 数组:

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

Also to add, if you or anyone else is using opencv.另外要补充的是,如果您或其他任何人正在使用 opencv。

 imgc=cv2.imread(file)

or to read in as grayscale或读入灰度

 imgc=cv2.imread(file,0)

If you will be doing some comparison between the images you may want to think about turning the array of pixels into histograms to normalise the data.如果您将在图像之间进行一些比较,您可能需要考虑将像素阵列转换为直方图以对数据进行标准化。

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

The above line firstly flattens your img array so you do lose the dimensionality of your image.上面的行首先展平了您的 img 数组,因此您确实会丢失图像的维度。 It then produces bins from 0 to 256 (for the grayscale image) and adds the counts from the img to these bins and returns them as hist which can then be plotted.然后它生成从 0 到 256(对于灰度图像)的 bin,并将来自 img 的计数添加到这些 bin 并将它们作为 hist 返回,然后可以绘制。 For example, if the 100 bin has a value of 20 it means that 20 pixels in your image had a value of 100.例如,如果 100 bin 的值为 20,则表示图像中 20 个像素的值为 100。

Hope this adds another possiblity to think about or to anyone looking to get started in opencv.希望这为任何希望开始使用 opencv 的人增加了另一种思考的可能性。

You can do that with Pillow , the getdata method gives you a flat array of the pixels, you can then build a matrix from that using the size of the image.您可以使用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)]

Thanks abarenet! 谢谢abarenet! Please use imageio instead of scipy as scipy is not being continued anymore. 请使用imageio而不是scipy因为scipy不再继续。 Simplifying abarnet's answer: 简化abarnet的答案:

  1. Install imageio 安装imageio

    pip3 install imageto

  2. python3 code: python3代码:

    If the image is of dimensions 260X340 , then rgb_matrix is an array of dimensions 260X340X3 如果图像的尺寸为260X340 ,则rgb_matrix是尺寸为260X340X3的数组

    from imageio import imread rgb_matrix = imread('image13.png') print(rgb_matrix[15][23])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM