我在指定的行中从以下Python3代码中收到错误。 x,y和z都是简单的2D numpy数组相同但尺寸相同,应该相同。然而他们的行为不同,y和z崩溃,而x工作正常。
import numpy as np
from PIL import Image
a = np.ones( ( 3,3,3), dtype='uint8' )
x = a[1,:,:]
y = a[:,1,:]
z = a[:,:,1]
imx = Image.fromarray(x) # ok
imy = Image.fromarray(y) # error
imz = Image.fromarray(z) # error
但这有效
z1 = 1*z
imz = Image.fromarray(z1) # ok
错误是:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python3\lib\site-packages\PIL\Image.py", line 1918, in fromarray
obj = obj.tobytes()
AttributeError: 'numpy.ndarray' object has no attribute 'tobytes'
那么x,y,z,z1之间有什么不同?我什么都不知道。
>>> z.dtype
dtype('uint8')
>>> z1.dtype
dtype('uint8')
>>> z.shape
(3, 4)
>>> z1.shape
(3, 4)
我在Windows 7企业版机器上使用Python 3.2.3,一切都是64位。
答案 0 :(得分:6)
我可以在ubuntu 12.04上使用Python 3.2.3,numpy 1.6.1和PIL 1.1.7-for-Python 3在http://www.lfd.uci.edu/~gohlke/pythonlibs/#pil上重现。之所以出现这种差异,是因为x的array_interface没有strides值,但是y和z是:
>>> x.__array_interface__['strides']
>>> y.__array_interface__['strides']
(9, 1)
>>> z.__array_interface__['strides']
(9, 3)
因此在这里采取了不同的分支:
if strides is not None:
obj = obj.tobytes()
文档提到了tostring
,而不是tobytes
:
# If obj is not contiguous, then the tostring method is called
# and {@link frombuffer} is used.
PIL 1.1.7的Python 2源代码使用tostring
:
if strides is not None:
obj = obj.tostring()
所以我怀疑这是在进行str / bytes更改的2到3转换期间引入的错误。只需在tobytes()
中将tostring()
替换为Image.py
即可,它应该有效:
Python 3.2.3 (default, May 3 2012, 15:54:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> from PIL import Image
>>>
>>> a = np.ones( ( 3,3,3), dtype='uint8' )
>>> x = a[1,:,:]
>>> y = a[:,1,:]
>>> z = a[:,:,1]
>>>
>>> imx = Image.fromarray(x) # ok
>>> imy = Image.fromarray(y) # now no error!
>>> imz = Image.fromarray(z) # now no error!
>>>
答案 1 :(得分:2)
同意DSM。我也遇到了与PIL 1.17相同的问题。
在我的情况下,我需要传输ndarray int图像并保存它。
x = np.asarray(img[:, :, 0] * 255., np.uint8)
image = Image.fromarray(x)
image.save("%s.png" % imgname)
我的错误和你的一样。
我随机尝试了其他方法:scipy.msic.imsave直接保存图像。
scipy.msic.imsave(imgname, x)
有效!不要忘记图片名称中的'.png'。