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

时间:2021-08-12 21:27:30

I have an RGB image. I want to convert it to numpy array. I did the following

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

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

it creates an array with no shape. I assume it is iplimage object.

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

How to do it?

怎么做?

Thanks

谢谢

8 个解决方案

#1


66  

You can use newer OpenCV python interface (if I'm not mistaken it is available since OpenCV 2.2). It natively uses numpy arrays:

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

import cv2
im = cv2.imread("abc.tiff")
print type(im)

result:

结果:

<type 'numpy.ndarray'>

#2


40  

PIL (Python Imaging Library) and Numpy work well together.

PIL(Python Imaging Library)和Numpy很好地协同工作。

I use the following functions.

我使用以下功能。

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 )

The 'Image.fromarray' is a little ugly because I clip incoming data to [0,255], convert to bytes, then create a grayscale image. I mostly work in gray.

'Image.fromarray'有点难看,因为我将输入数据剪辑为[0,255],转换为字节,然后创建灰度图像。我大多是灰色的。

An RGB image would be something like:

RGB图像类似于:

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

#3


9  

You can also use matplotlib for this.

您也可以使用matplotlib。

import matplotlib.image as mpimg

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

output: <class 'numpy.ndarray'>

输出: 'numpy.ndarray'>

#4


6  

You need to use cv.LoadImageM instead of cv.LoadImage:

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

Late answer, but I've come to prefer the imageio module to the other alternatives

迟到的答案,但我更喜欢imageio模块到其他选择

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

Similar to cv2.imread(), it produces a numpy array by default, but in RGB form.

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

#7


1  

When using the answer from David Poole I get a SystemError with gray scale PNGs and maybe other files. My solution is:

当使用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' )

Actually img.getdata() would work for all files, but it's slower, so I use it only when the other method fails.

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

#8


0  

I also adopted imageio, but I found the following machinery useful for pre- and post-processing:

我也采用了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)

The rationale is that I am using numpy for image processing, not just image displaying. For this purpose, uint8s are awkward, so I convert to floating point values ranging from 0 to 1.

理由是我使用numpy进行图像处理,而不仅仅是图像显示。为此,uint8s很笨拙,所以我转换为从0到1的浮点值。

When saving images, I noticed I had to cut the out-of-range values myself, or else I ended up with a really gray output. (The gray output was the result of imageio compressing the full range, which was outside of [0, 256), to values that were inside the range.)

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

There were a couple other oddities, too, which I mentioned in the comments.

还有一些其他奇怪之处,我在评论中提到过。

#1


66  

You can use newer OpenCV python interface (if I'm not mistaken it is available since OpenCV 2.2). It natively uses numpy arrays:

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

import cv2
im = cv2.imread("abc.tiff")
print type(im)

result:

结果:

<type 'numpy.ndarray'>

#2


40  

PIL (Python Imaging Library) and Numpy work well together.

PIL(Python Imaging Library)和Numpy很好地协同工作。

I use the following functions.

我使用以下功能。

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 )

The 'Image.fromarray' is a little ugly because I clip incoming data to [0,255], convert to bytes, then create a grayscale image. I mostly work in gray.

'Image.fromarray'有点难看,因为我将输入数据剪辑为[0,255],转换为字节,然后创建灰度图像。我大多是灰色的。

An RGB image would be something like:

RGB图像类似于:

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

#3


9  

You can also use matplotlib for this.

您也可以使用matplotlib。

import matplotlib.image as mpimg

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

output: <class 'numpy.ndarray'>

输出: 'numpy.ndarray'>

#4


6  

You need to use cv.LoadImageM instead of cv.LoadImage:

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

Late answer, but I've come to prefer the imageio module to the other alternatives

迟到的答案,但我更喜欢imageio模块到其他选择

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

Similar to cv2.imread(), it produces a numpy array by default, but in RGB form.

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

#7


1  

When using the answer from David Poole I get a SystemError with gray scale PNGs and maybe other files. My solution is:

当使用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' )

Actually img.getdata() would work for all files, but it's slower, so I use it only when the other method fails.

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

#8


0  

I also adopted imageio, but I found the following machinery useful for pre- and post-processing:

我也采用了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)

The rationale is that I am using numpy for image processing, not just image displaying. For this purpose, uint8s are awkward, so I convert to floating point values ranging from 0 to 1.

理由是我使用numpy进行图像处理,而不仅仅是图像显示。为此,uint8s很笨拙,所以我转换为从0到1的浮点值。

When saving images, I noticed I had to cut the out-of-range values myself, or else I ended up with a really gray output. (The gray output was the result of imageio compressing the full range, which was outside of [0, 256), to values that were inside the range.)

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

There were a couple other oddities, too, which I mentioned in the comments.

还有一些其他奇怪之处,我在评论中提到过。