0

我需要对从图像读取的值的二维数组执行一些操作,然后使用生成的二维数组创建图像。我正在使用 python 列表来表示二维数组。

发生了一些非常奇怪的事情;二维数组(列表列表)中的值似乎在我标记的两个打印调用之间的某个时刻变为“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

然后两条print语句显示data中的所有元素都是77

到底是怎么回事?我不是 python 专家,但我想不出任何合理的理由为什么列表值会这样改变。

我已经尝试了以下行,以防像素访问器正在做一些奇怪的事情:

data[x][y] = 0 + int(pix[x, y])

但仍然得到相同的结果。我也尝试过使用 RGB 图像而不是灰度图像。

我应该明确表示,我绝对不会对这两个打印调用之间的数据做任何事情。上面的代码正是我将原始程序简化为的代码(在发现我所有的“结果”图像文件都是黑色之后)。

4

2 回答 2

3

你的问题在于这条线:

data = [ [255] * image.size[1] ] * image.size[0]

image.size[1]这将创建一个填充了 value的长度列表255。然后,您创建image.size[0]同一列表的引用并将所有这些引用打包到另一个列表中。因此,当您更改时a[1][1],您也会更改a[0][1]等,a[2][1]因为a[0], a[1], a[2],是对同一个列表...的引用。

这是一个简单的例子:

a = [[255]*10]*10
a[1][1] = 77
print (a)

最简单的解决方法是:

a = [[255]*10 for _ in range(10)]

因为这会创建 10 个新列表,而不是对同一列表的引用列表。

于 2012-10-09T11:22:44.230 回答
1

您最好更改datadata = []附加每一行。

data = []
pix = image.load()
for y in xrange(image.size[1]):
    data.append([pix[x, y] for x in xrange(image.size[0])])
于 2012-10-09T11:25:46.850 回答