我需要对从图像读取的2D数组值执行一些操作,然后使用生成的2D数组创建图像。我正在使用python列表来表示2D数组。
发生了一件非常奇怪的事情;在我标记的两个打印调用之间的某个点上,2D数组(列表列表)中的值似乎变为“0”。也就是说,它们似乎可以从图像中正确读取......但是然后以某种方式设置为零。
代码:
image = Image.open("test.png").convert("L")
data = [ [255] * image.size[1] ] * image.size[0]
pix = image.load()
for x in range(0, image.size[0]):
for y in range(0, image.size[1]):
data[x][y] = pix[x, y]
#data[x][y] = 77
print "1. data[x][y] = " + str(data[x][y]) + " .vs. " + str(pix[x, y]) # Prints correct values
for x in range(0, image.size[0]):
for y in range(0, image.size[1]):
print "2. data[x][y] = " + str(data[x][y]) + " .vs. " + str(pix[x, y]) # Always prints "0 .vs. [correct value]"
但是,如果我注释掉该行
data[x][y] = pix[x, y]
并取消注释:
data[x][y] = 77
然后两个打印语句显示数据中的所有元素都是77
发生了什么事?我不是python的专家,但我想不出任何明智的理由为什么列表值会像这样改变。
我尝试了以下一行,以防像素访问者做了一些奇怪的事情:
data[x][y] = 0 + int(pix[x, y])
但仍然得到相同的结果。我也尝试过使用RGB图像而不是灰度图像。
我应该说清楚,我绝对不会对这两个打印调用之间的数据做任何事情。上面的代码正是我将原始程序减少到(在发现我的所有“结果”图像文件都是黑色之后)。
答案 0 :(得分:3)
你问题在于这一行:
data = [ [255] * image.size[1] ] * image.size[0]
这会创建一个填充值image.size[1]
的长度为255
的列表。然后,您创建对{em>相同列表的image.size[0]
个引用,并将所有这些引用打包到另一个列表中。因此,当您更改a[1][1]
时,您还会更改a[0][1]
和a[2][1]
等,因为a[0]
,a[1]
,a[2]
,{{1} }是对相同列表的引用。
这是一个简单的例子:
...
最简单的解决方法是:
a = [[255]*10]*10
a[1][1] = 77
print (a)
因为这会创建10个新列表,而不是对同一列表的引用列表。
答案 1 :(得分:1)
您最好将data
更改为data = []
并追加每一行。
data = []
pix = image.load()
for y in xrange(image.size[1]):
data.append([pix[x, y] for x in xrange(image.size[0])])