Dar*_*enW 5 python numpy attributeerror python-imaging-library
我在指定的行中从以下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
Run Code Online (Sandbox Code Playgroud)
但这很有效
z1 = 1*z
imz = Image.fromarray(z1) # ok
Run Code Online (Sandbox Code Playgroud)
错误是:
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'
Run Code Online (Sandbox Code Playgroud)
那么x,y,z,z1之间有什么不同?我什么都不知道.
>>> z.dtype
dtype('uint8')
>>> z1.dtype
dtype('uint8')
>>> z.shape
(3, 4)
>>> z1.shape
(3, 4)
Run Code Online (Sandbox Code Playgroud)
我在Windows 7企业版机器上使用Python 3.2.3,一切都是64位.
我可以在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)
Run Code Online (Sandbox Code Playgroud)
所以这里有一个不同的分支:
if strides is not None:
obj = obj.tobytes()
Run Code Online (Sandbox Code Playgroud)
文档提到tostring,而不是tobytes:
# If obj is not contiguous, then the tostring method is called
# and {@link frombuffer} is used.
Run Code Online (Sandbox Code Playgroud)
PIL 1.1.7的Python 2源代码使用tostring:
if strides is not None:
obj = obj.tostring()
Run Code Online (Sandbox Code Playgroud)
所以我怀疑这是在2到3转换期间引入的错误,其中进行了str /字节更改.只需更换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!
>>>
Run Code Online (Sandbox Code Playgroud)