如何将RGB图像转换为numpy数组?


Answers:


142

您可以使用较新的OpenCV python接口(如果我没记错的话,自Ope​​nCV 2.2起就可以使用)。它本机使用numpy数组:

import cv2
im = cv2.imread("abc.tiff",mode='RGB')
print type(im)

结果:

<type 'numpy.ndarray'>

94
注意cv2.imread()以BGR而不是RGB返回一个numpy数组。
PND

6
@pnd您的评论是神圣的!
Eduardo Pignatelli,

4
将来的参考: $ pip install opencv-python安装opencv
Kyle C

2
TypeError: 'mode' is an invalid keyword argument for imread()
Rishabh Agrahari'3

8
OpenCV似乎放弃了mode争论。请参阅下面的答案以获取更新的方法。
belvederef

73

PIL(Python影像库)和Numpy可以很好地协同工作。

我使用以下功能。

from PIL import Image
import numpy as np

def load_image( infilename ) :
    img = Image.open( infilename )
    img.load()
    data = np.asarray( img, dtype="int32" )
    return data

def save_image( npdata, outfilename ) :
    img = Image.fromarray( np.asarray( np.clip(npdata,0,255), dtype="uint8"), "L" )
    img.save( outfilename )

“ Image.fromarray”有点难看,因为我将传入的数据裁剪为[0,255],转换为字节,然后创建灰度图像。我大部分时间都是灰色工作。

RGB图像如下所示:

 outimg = Image.fromarray( ycc_uint8, "RGB" )
 outimg.save( "ycc.tif" )

1
这失败并显示错误,TypeError: long() argument must be a string or a number, not 'PixelAccess'并且查看PIL PixelAccess类的文档,它似乎没有提供能够np.array将其基础数据转换为ndarray格式的方法。您只需省略的使用,img.load()而仅处理的结果Image.open(...)
伊利

img.load()解决了PIL中一个奇怪的缓存问题。除非明确需要,否则不会加载数据。除了使用Pillow(PIL分支)时将“ import Image”更改为“ from PIL import Image”以外,该示例对我而言仍然有效。
David Poole

支持仅使用PIL而非OpenCV。我不反对OpenCV。
progyammer


19

截至今天,您最好的选择是使用:

img = cv2.imread(image_path)   # reads an image in the BGR format
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)   # BGR -> RGB

您将看到img一个类型为numpy的数组:

<class 'numpy.ndarray'>

12

答案较晚,但imageio与其他替代方案相比,我更喜欢该模块

import imageio
im = imageio.imread('abc.tiff')

与相似cv2.imread(),默认情况下会生成numpy数组,但格式为RGB。


7

您需要使用cv.LoadImageM而不是cv.LoadImage:

In [1]: import cv
In [2]: import numpy as np
In [3]: x = cv.LoadImageM('im.tif')
In [4]: im = np.asarray(x)
In [5]: im.shape
Out[5]: (487, 650, 3)

非常感谢...您能否也帮助我找出如果我使用'cv.CreateImage(width,height,channels)'创建图像...如何将其转换为numpy数组?

我认为您需要改用cv.CreateMat或使用cv.CreateMat并使用cv.CvtColor或类似的东西从图像复制到垫子。看一下Paul发布到上面的链接。
贾斯汀·皮

3

当使用David Poole的答案时,出现灰度PNG以及其他文件的SystemError。我的解决方案是:

import numpy as np
from PIL import Image

img = Image.open( filename )
try:
    data = np.asarray( img, dtype='uint8' )
except SystemError:
    data = np.asarray( img.getdata(), dtype='uint8' )

实际上img.getdata()适用于所有文件,但速度较慢,因此仅在其他方法失败时才使用它。


2

OpenCV映像格式支持numpy数组接口。可以创建一个辅助功能来支持灰度或彩色图像。这意味着可以使用numpy slice而不是图像数据的完整副本方便地完成BGR-> RGB转换。

注意:这是一个大技巧,因此修改输出数组也将更改OpenCV图像数据。如果要复制,请.copy()在阵列上使用方法!

import numpy as np

def img_as_array(im):
    """OpenCV's native format to a numpy array view"""
    w, h, n = im.width, im.height, im.channels
    modes = {1: "L", 3: "RGB", 4: "RGBA"}
    if n not in modes:
        raise Exception('unsupported number of channels: {0}'.format(n))
    out = np.asarray(im)
    if n != 1:
        out = out[:, :, ::-1]  # BGR -> RGB conversion
    return out

1

我也采用了imageio,但发现以下机器可用于预处理和后期处理:

import imageio
import numpy as np

def imload(*a, **k):
    i = imageio.imread(*a, **k)
    i = i.transpose((1, 0, 2))  # x and y are mixed up for some reason...
    i = np.flip(i, 1)  # make coordinate system right-handed!!!!!!
    return i/255


def imsave(i, url, *a, **k):
    # Original order of arguments was counterintuitive. It should
    # read verbally "Save the image to the URL" — not "Save to the
    # URL the image."

    i = np.flip(i, 1)
    i = i.transpose((1, 0, 2))
    i *= 255

    i = i.round()
    i = np.maximum(i, 0)
    i = np.minimum(i, 255)

    i = np.asarray(i, dtype=np.uint8)

    imageio.imwrite(url, i, *a, **k)

原因是我使用numpy进行图像处理,而不仅仅是图像显示。为此,uint8s很尴尬,因此我将其转换为从0到1的浮点值。

保存图像时,我注意到我必须自己剪切超出范围的值,否则最终会得到真正的灰色输出。(灰色输出是将整个范围(在[0,256]之外)压缩到范围内的值的图像的结果。)

我在评论中也提到了其他一些奇怪之处。


1

您可以使用numpy和轻松获得RGB图片的numpy数组Image from PIL

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

im = Image.open('*image_name*') #These two lines
im_arr = np.array(im) #are all you need
plt.imshow(im_arr) #Just to verify that image array has been constructed properly

0

使用以下语法加载图像:

from keras.preprocessing import image

X_test=image.load_img('four.png',target_size=(28,28),color_mode="grayscale"); #loading image and then convert it into grayscale and with it's target size 
X_test=image.img_to_array(X_test); #convert image into array
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.