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

时间:2011-10-14 04:13:07

标签: python image opencv numpy

我有一张RGB图像。我想将它转换为numpy数组。我做了以下

im = cv.LoadImage("abc.tiff")
a = numpy.asarray(im)

它创建一个没有形状的数组。我认为它是一个iplimage对象。

14 个答案:

答案 0 :(得分:97)

你可以使用更新的OpenCV python接口(如果我没弄错,它可以从OpenCV 2.2开始使用)。它原生使用numpy数组:

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

结果:

<type 'numpy.ndarray'>

答案 1 :(得分:50)

PIL(Python Imaging Library)和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" )

答案 2 :(得分:32)

您也可以使用matplotlib

from matplotlib.image import imread

img = imread('abc.tiff')
print(type(img))

输出: <class 'numpy.ndarray'>

答案 3 :(得分:8)

迟到的回答,但我更喜欢imageio模块和其他替代方案

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

cv2.imread()类似,它默认生成一个numpy数组,但是以RGB格式生成。

答案 4 :(得分:6)

您需要使用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)

答案 5 :(得分:2)

def opencv_image_as_array(im):
  """Interface image from OpenCV's native format to a numpy array.

  note: this is a slicing trick, and modifying the output array will also change
  the OpenCV image data.  if you want a copy, use .copy() method on the array!
  """
  import numpy as np
  w, h, n = im.width, im.height, im.channels
  modes = {1:"L", 3:"RGB"}#, 4:"RGBA"}
  if n not in modes:
    raise StandardError('unsupported number of channels: {0}'.format(n))
  out = np.asarray(im) if n == 1 else np.asarray(im)[:,:,::-1]  ## BGR -> RGB
  return out

答案 6 :(得分:2)

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

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

答案 7 :(得分:1)

当使用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()适用于所有文件,但速度较慢,所以我只在其他方法失败时使用它。

答案 8 :(得分:1)

从今天起,最好的选择是使用:

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'>

答案 9 :(得分:1)

使用以下语法加载图像:-

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

答案 10 :(得分:0)

我也采用了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的浮点值。

保存图像时,我注意到我必须自己削减超出范围的值,否则我最终会得到一个非常灰色的输出。 (灰度输出是imageio压缩整个范围(超出[0,256])到范围内的值的结果。)

还有其他一些奇怪的东西,我在评论中提到过。

答案 11 :(得分:0)

使用Keras:

from keras.preprocessing import image
  
img = image.load_img('path_to_image', target_size=(300, 300))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])

答案 12 :(得分:0)

尝试对将图像加载到 numpy 数组的选项进行计时,它们非常相似。选择 plt.imread 以实现简单和快速。

def time_this(function, times=100):
    cum_time = 0
    for t in range(times):
        st = time.time()
        function()
        cum_time += time.time() - st
    return cum_time / times

import matplotlib.pyplot as plt
def load_img_matplotlib(img_path):
    return plt.imread(img_path)

import cv2
def load_img_cv2(img_path):
    return cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2RGB)

from PIL import Image
import numpy as np
def load_img_pil(img_path):
    img = Image.open(img_path)
    img.load()
    return np.asarray( img, dtype="int32" )

if __name__=='__main__':
    img_path = 'your_image_path'
    for load_fn in [load_img_pil, load_img_cv2, load_img_matplotlib]:
        print('-'*20)
        print(time_this(lambda: load_fn(img_path)), 10000)

结果:

--------------------
0.0065201687812805175 10000  PIL, as in [the second answer][1]https://stackoverflow.com/a/7769424/16083419)
--------------------
0.0053211402893066405 10000  CV2
--------------------
0.005320906639099121 10000  matplotlib

答案 13 :(得分:0)

你可以试试下面的方法。链接到 docs

    tf.keras.preprocessing.image.img_to_array(
    img, data_format=None, dtype=None
)
from PIL import Image
img_data = np.random.random(size=(100, 100, 3))
img = tf.keras.preprocessing.image.array_to_img(img_data)
array = tf.keras.preprocessing.image.img_to_array(img)