Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PIL library Image.fromarray()导致AttributeError:';元组';对象没有属性'__阵列接口x27;_Python_Image_Ubuntu_Python Imaging Library - Fatal编程技术网

Python PIL library Image.fromarray()导致AttributeError:';元组';对象没有属性'__阵列接口x27;

Python PIL library Image.fromarray()导致AttributeError:';元组';对象没有属性'__阵列接口x27;,python,image,ubuntu,python-imaging-library,Python,Image,Ubuntu,Python Imaging Library,我正在使用物理模拟器pybullet,并希望使用以下两行代码在我的模拟中保存来自“虚拟摄影机”的图像 camera1 = pybullet.getCameraImage(900,600) im1 = Image.fromarray(camera1[2]) 第一行使用pybullet的getCameraImage函数返回未处理的图像camera1[2]是RGBA格式的像素颜色列表,每种颜色的范围为[0..255] 第二行应该获取该数组并将其转换为图像,然后保存并查看 运行代码时,我收到以下错误消

我正在使用物理模拟器pybullet,并希望使用以下两行代码在我的模拟中保存来自“虚拟摄影机”的图像

camera1 = pybullet.getCameraImage(900,600)
im1 = Image.fromarray(camera1[2])
第一行使用pybullet的getCameraImage函数返回未处理的图像
camera1[2]
是RGBA格式的像素颜色列表,每种颜色的范围为[0..255] 第二行应该获取该数组并将其转换为图像,然后保存并查看

运行代码时,我收到以下错误消息:

Traceback (most recent call last):
  File "generate_dataset.py", line 43, in <module>
    im1 = Image.fromarray(camera1[2], "RGBA")
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2140, in 
fromarray
    arr = obj.__array_interface__
AttributeError: 'tuple' object has no attribute '__array_interface__'
将最后一行更改为:
im1=Image.fromarray(imarray.astype('uint8'))

导致:

Traceback (most recent call last):
  File "generate_dataset.py", line 42, in <module>
    im1 = Image.fromarray(imarray)
  File "/usr/local/lib/python2.7/dist-packages/PIL/Image.py", line 2431, in fromarray
    raise TypeError("Cannot handle this data type")
TypeError: Cannot handle this data type
Traceback (most recent call last):
  File "generate_dataset.py", line 42, in <module>
    im1 = Image.fromarray(imarray.astype('uint8'))
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2165, in fromarray
    size = shape[1], shape[0]
IndexError: tuple index out of range
回溯(最近一次呼叫最后一次):
文件“generate_dataset.py”,第42行,在
im1=Image.fromarray(imarray.astype('uint8'))
fromarray中的文件“/usr/lib/python3/dist packages/PIL/Image.py”,第2165行
大小=形状[1],形状[0]
索引器错误:元组索引超出范围
额外信息,如果需要

Pybullet文档:

PIL文件:

我的完整代码:

import pybullet as p
import pybullet_data
import time
from PIL import Image
from random import *
import numpy as np

nExamples = 200

for n in range(0, nExamples):

  print ("Running example " + str(n))

  physicsClient = p.connect(p.DIRECT) #or p.GUI for graphical version
  p.setAdditionalSearchPath(pybullet_data.getDataPath()) #optionally
  p.setGravity(0,0,-10)
  planeId = p.loadURDF("ground.urdf")
  p.resetDebugVisualizerCamera( cameraDistance=1, cameraYaw=0, cameraPitch=-30, cameraTargetPosition=[0,0,0])

  x1 = uniform(-0.03,0.03)
  y1 = uniform(-0.03,0.03)
  x2 = x1 + uniform(-0.03,0.03)
  y2 = y1 + uniform(-0.03,0.03)
  cubeStartPos = [0.0,0,0.025]
  cubeStartPos1 = [x1,y1,0.075]
  cubeStartPos2 = [x2,y2,0.125]
  yaw0 = uniform(0,np.pi/2)
  yaw1 = uniform(0,np.pi/2)
  yaw2 = uniform(0,np.pi/2)
  cubeStartOrientation0 = p.getQuaternionFromEuler([0,0,yaw0])
  cubeStartOrientation1 = p.getQuaternionFromEuler([0,0,yaw1])
  cubeStartOrientation2 = p.getQuaternionFromEuler([0,0,yaw2])
  boxId = p.loadURDF("red_block.urdf",cubeStartPos, cubeStartOrientation0)
  boxId1 = p.loadURDF("green_block.urdf",cubeStartPos1, cubeStartOrientation1)
  boxId2 = p.loadURDF("blue_block.urdf",cubeStartPos2, cubeStartOrientation2)

  #saving the initial image...
  camera1 = p.getCameraImage(900,600)
  imarray = np.asarray(camera1[2])
  im1 = Image.fromarray(imarray.astype('uint8'))

  for i in range (250):
    p.stepSimulation()
    time.sleep(1./20.)

  camera2 = p.getCameraImage(900,600)

  #saving the image after blocks movement --> if stable this image is equal to the initial...
  im2 = Image.fromarray(camera2[2])

  #Are the images different? (Is it unstable?) --> if yes then diff is large, otherwise, diff is negligible
  diff = (camera2[2] - camera1[2]).sum()
  print("DIFFERENCE =", diff)
  if abs(diff) < 100000:
    im1.save("images/stable/image_%d.png" % n)
  else:
    im1.save("images/unstable/image_%d.png" % n)

  #cropping images
  cropped = im1.crop((350,200,550,400))
  cropped.save("images/cropped/image_%d.png" % n)

  p.disconnect()

  print ("Reached end of loop\n")
将pybullet作为p导入
导入PYU数据
导入时间
从PIL导入图像
从随机导入*
将numpy作为np导入
例如:200
对于范围内的n(0,示例):
打印(“运行示例”+str(n))
physicclient=p.connect(p.DIRECT)#或p.GUI用于图形版本
p、 setAdditionalSearchPath(pybullet_data.getDataPath())#可选
p、 设定重力(0,0,-10)
planeId=p.loadURDF(“ground.urdf”)
p、 ResetDebugVisualizationRCAMera(CameradInstance=1,cameraYaw=0,CameraPictch=-30,CameratTargetPosition=[0,0,0])
x1=均匀(-0.03,0.03)
y1=均匀(-0.03,0.03)
x2=x1+均匀(-0.03,0.03)
y2=y1+均匀(-0.03,0.03)
cubeStartPos=[0.0,0,0.025]
cubeStartPos1=[x1,y1,0.075]
cubeStartPos2=[x2,y2,0.125]
yaw0=均匀(0,np.pi/2)
yaw1=均匀(0,np.pi/2)
yaw2=均匀(0,np.pi/2)
cubeStartOrientation0=p.getQuaternionFromEuler([0,0,yaw0])
cubeStartOrientation1=p.getQuaternionFromEuler([0,0,yaw1])
cubeStartOrientation2=p.getQuaternionFromEuler([0,0,yaw2])
boxId=p.loadURDF(“red_block.urdf”,cubeStartPos,cubeStartOrientation0)
boxId1=p.loadURDF(“green_block.urdf”,cubeStartPos1,cubeStartOrientation1)
boxId2=p.loadURDF(“蓝色块,urdf”,立方星定位2,立方星定位2)
#正在保存初始图像。。。
camera1=p.getCameraImage(900600)
imarray=np.asarray(camera1[2])
im1=Image.fromarray(imarray.astype('uint8'))
对于范围(250)内的i:
p、 步骤模拟()
时间。睡眠(1/20)
camera2=p.getCameraImage(900600)
#块移动后保存图像-->如果此图像等于初始值。。。
im2=Image.fromarray(camera2[2])
#图像不同吗?(是否不稳定?-->如果是,则差异较大,否则差异可忽略不计
diff=(camera2[2]-camera1[2]).sum()
打印(“差异=”,差异)
如果abs(差值)<100000:
im1.保存(“images/stable/image\uu%d.png”%n)
其他:
im1.保存(“图像/不稳定/图像\uu%d.png”%n)
#裁剪图像
裁剪=im1.裁剪((350200550400))
剪切。保存(“图像/剪切/图像\u%d.png”%n)
p、 断开连接()
打印(“已到达循环的末尾\n”)

从您的描述中不清楚
camera1[2]
是连续R、G、B、a值的平面列表,还是RGBA元组的列表。因此,我将向您展示如何阅读这两个选项

您的主要问题是,您的数据不包含宽度和高度信息,因此我们需要以某种方式提供这些信息。一种方法是将数据读入正确形状的3D Numpy数组。但我们也可以通过使用适当的图像方法直接在PIL中进行

在我的演示中,我使用Python循环来创建一些简单的RGBA数据

此脚本创建RGBA元组列表

from PIL import Image

maxval = 255
width, height = 400, 300

# Display size info
size = width * height
fmt = 'Width: {}, Height: {}, Pixels: {}, Bytes: {}'
print(fmt.format(width, height, size, size * 4))

# Make a 2D gradient that starts at black in the top left corner,
# with red & green increasing horizontally, blue increasing vertically.
# This would be much faster using Numpy instead of Python loops.
pixels = []
# Make all pixels fully opaque
alpha = maxval
for y in range(height):
    blu = maxval * y // height
    for x in range(width):
        red = gre = maxval * x // width
        # Make a single RGBA pixel as a tuple
        pix = red, gre, blu, alpha
        # And save it
        pixels.append(pix)

# Show that the size of `pixels` is correct and show the first few pixels
print('Size:', len(pixels))
print(pixels[:8])

# Make a new image object. All pixels are set to black. 
img = Image.new('RGBA', (width, height))
# Copy the pixel data to the Image
img.putdata(pixels)
img.show()
img.save('test1.png') 
输出

Width: 400, Height: 300, Pixels: 120000, Bytes: 480000
Size: 120000
[(0, 0, 0, 255), (0, 0, 0, 255), (1, 1, 0, 255), (1, 1, 0, 255), (2, 2, 0, 255), (3, 3, 0, 255), (3, 3, 0, 255), (4, 4, 0, 255)]
Width: 400, Height: 300, Pixels: 120000, Bytes: 480000
Size: 480000
[0, 0, 0, 255, 0, 0, 0, 255, 1, 1, 0, 255, 1, 1, 0, 255, 2, 2, 0, 255, 3, 3, 0, 255, 3, 3, 0, 255, 4, 4, 0, 255]
test1.png


此脚本创建一个R、G、B、a值的平面列表。它使用Python3
bytes
对象,因此无法在Python2上正常工作

from PIL import Image

maxval = 255
width, height = 400, 300

# Display size info
size = width * height
fmt = 'Width: {}, Height: {}, Pixels: {}, Bytes: {}'
print(fmt.format(width, height, size, size * 4))

# Make a 2D gradient that starts at black in the top left corner,
# with red & green increasing horizontally, blue increasing vertically.
# This would be much faster using Numpy instead of Python loops.
rgba = []
# Make all pixels fully opaque
alpha = maxval
for y in range(height):
    blu = maxval * y // height
    for x in range(width):
        red = gre = maxval * x // width
        # Make a single RGBA pixel as a tuple
        pix = red, gre, blu, alpha
        # And save each of red, gre, blu, alpha to rgba. 
        # By using `.extend` we create a flat list
        rgba.extend(pix)

# Show that the size of `rgba` is correct and show the first few values.
print('Size:', len(rgba))
print(rgba[:32])

# Convert the rgba list to bytes.
rgba = bytes(rgba)
# Make a new image object from the bytes
img = Image.frombytes('RGBA', (width, height), rgba)
img.show()
img.save('test2.png')
输出

Width: 400, Height: 300, Pixels: 120000, Bytes: 480000
Size: 120000
[(0, 0, 0, 255), (0, 0, 0, 255), (1, 1, 0, 255), (1, 1, 0, 255), (2, 2, 0, 255), (3, 3, 0, 255), (3, 3, 0, 255), (4, 4, 0, 255)]
Width: 400, Height: 300, Pixels: 120000, Bytes: 480000
Size: 480000
[0, 0, 0, 255, 0, 0, 0, 255, 1, 1, 0, 255, 1, 1, 0, 255, 2, 2, 0, 255, 3, 3, 0, 255, 3, 3, 0, 255, 4, 4, 0, 255]

文件“test2.png”与“test1.png”完全相同。

您说过“
camera1[2]
是RGBA格式的像素颜色列表”(虽然从错误消息中可以看出,它实际上是一个元组,但在这里不会有什么区别)。但是它是一个整型值的平面列表,还是一个RGBA元组的嵌套列表?顺便说一句,看起来您同时使用了Python2和Python3。当您试图调试东西时,这可能会让人困惑。我建议您坚持使用Python3,除非您需要使用一些尚未移植到Python3的古老库。这就解决了它!将数组转换为字节,然后使用
frombytes
方法(如第二个示例中所示),处理图像时不会出现错误。非常感谢你!