在.append之后使用时,Numpy.unique失败

时间:2018-01-24 20:24:08

标签: python-3.x numpy

我有一个小函数可以从图像中提取灰度值并将它们缩小到0到1之间的均匀分度。函数:

from PIL import Image
import numpy as np
import math

def get_binary(I):
    Bin = []
    unique_vals = np.unique(I)
    print(unique_vals)
    for y in range(I.size[1]):
        c = []
        for x in range(I.size[0]):
            for n in range(len(unique_vals)):
                val = I.getpixel((x,y))
                if val == 0 or val == (0,0,0):
                    c.append(0)
                elif val == unique_vals[n]:
                    c.append(1/(len(unique_vals)-1)*n)

        Bin.append(c)
    #print(len(np.unique(c)))
    #print(np.shape(Bin))
    #print(len(np.unique(Bin)))
    return Bin

img = Image.open('Si_Al_Combo.png')
get_binary(img)

它依赖于numpy.unique()方法来确定图像中存在哪些值以及它们将变为0到1之间的值。在我的测试用例中,我的图像有3个值(0,127,255),它们分别变为0,0.5和1.0,因此print(len(np.unique(c)))应该(并且确实)输出3,但是print(len(np.unique(Bin)))似乎将Bin中的每个单独的价值解释为唯一的,它们不是,也不应该是。发生了什么事?

编辑:这是我用来测试此功能的图像
A grayscale image with only three values: 0, 127, 255

1 个答案:

答案 0 :(得分:3)

您将一个参差不齐的列表列表传递给np.unique:也就是说,您已经传递了一系列数字列表,但内部列表并不都是相同的长度。这意味着当np.unique tries to convert its input to an array(这是它做的第一件事)时,它最终会得到一个dtype object的一维数组,其中每个元素都是一个Python列表包含一行变换后的图像。

然后,np.unique继续查找不同子列表的数量,而不是收集在一起的所有子列表中的不同的数量。

如果列表的输入列表没有参差不齐,则不会发生这种情况:np.unique会转换为2d数字数组,然后没有{ {1}}参数,在找到唯一值之前会变平。

这是一个较小阵列的演示:首先,列表中包含一个参差不齐的列表:

axis

然后在所有子列表具有相同长度的情况下:

>>> x = [[1, 2, 3], [0, 1, 0, 2], [2, 3, 4]]
>>> np.asanyarray(x)  # this is what ends up being analysed by np.unique
array([list([1, 2, 3]), list([0, 1, 0, 2]), list([2, 3, 4])], dtype=object)
>>> np.unique(x)
array([list([0, 1, 0, 2]), list([1, 2, 3]), list([2, 3, 4])], dtype=object)

看起来你首先有一个参差不齐的列表列表是你的代码中的一个错误,并且是因为你想要追加>>> x = [[1, 2, 3], [3, 1, 2], [2, 2, 1]] >>> np.asanyarray(x) array([[1, 2, 3], [3, 1, 2], [2, 2, 1]]) >>> np.unique(x) array([1, 2, 3]) 次。请注意,如果0I.getpixel((x,y)),则最终会在内部循环的每次迭代上将0附加到0。也就是说,我怀疑你的内循环应该是这样的:

c

顺便说一句,您可能还想查看np.uniqueval = I.getpixel((x, y)) if val == 0 or val == (0,0,0): c.append(0) else: for n in range(len(unique_vals)): if val == unique_vals[n]: c.append(1/(len(unique_vals)-1)*n) 参数。如果您将原始图像作为阵列提供,这基本上可以完成转换所需的所有工作。这是一个玩具示例,其形状很小return_inverse输入图像:

(4, 3)

看Ma,不用循环!