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'>
输出:
#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'>
输出:
#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.
还有一些其他奇怪之处,我在评论中提到过。