我有一个小函数可以从图像中提取灰度值并将它们缩小到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
中的每个单独的价值解释为唯一的,它们不是,也不应该是。发生了什么事?
答案 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])
次。请注意,如果0
为I.getpixel((x,y))
,则最终会在内部循环的每次迭代上将0
附加到0
。也就是说,我怀疑你的内循环应该是这样的:
c
顺便说一句,您可能还想查看np.unique
的val = 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,不用循环!