2012-06-01 7 views
5

次のPython3コードのエラーが表示されます。 x、y、zはすべて、同じサイズでも同じサイズの普通の2D numpy配列であり、同じように動作するはずです。しかし、彼らは違った動きをしていますが、yとzはクラッシュし、xはうまくいきます。PILのfromArray関数で次元依存のAttributeErrorを引き起こす原因は何ですか?

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 EnterpriseマシンでPython 3.2.3を使用しています。すべて64ビットです。

+0

Ubuntu 12.04のpython 2.7でエラーはありません。 – user545424

答えて

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.__array_interface__['strides'] 
(9, 1) 
>>> z.__array_interface__['strides'] 
(9, 3) 

ので、異なる分岐がここに取られる:

if strides is not None: 
    obj = obj.tobytes() 

ドキュメントは、tostringない言及xのarray_interfaceが進歩値が、yの、およびzのDOを持っていないので、違いが起こります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への変換時に発生したエラーと思われます。単にImage.pytostring()tobytes()を交換し、それが動作するはずです:

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

ありがとうございます。これは、 'arr2 = arr.copy();のように配列のコピーを作成するという回避策を指摘しました。 Image.fromarray(arr2、 'L') 'を返します。これは' .fromarray(arr、...) 'が失敗しても機能します。 –

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) 

imagenameに '.png'を忘れないでください。

関連する問題