我最初从初始数组创建了一个子数组,用于从中生成灰度图像:Deleting consecutive numbers from a numpy array和Remove following duplicates in a numpy array
但是现在我想对彩色图像做同样的事情,我真的很困惑。我已经研究了好几天了,根本无法理解如何处理它。
问题在于正方形的大小不同,我希望每个正方形用相同的颜色表示一个像素。
彩色图片:
我的灰度图像代码:
from PIL import Image
import numpy as np
name1 = raw_input("What is the name of the .png file you want to open? ")
filename1 = "%s.png" % name1
img = Image.open(filename1).convert('L') # convert image to 8-bit grayscale
WIDTH, HEIGHT = img.size
a = list(img.getdata()) # convert image data to a list of integers
# convert that to 2D list (list of lists of integers)
a = np.array ([a[offset:offset+WIDTH] for offset in range(0, WIDTH*HEIGHT, WIDTH)])
print " "
print "Intial array from image:" #print as array
print " "
print a
rows_mask = np.insert(np.diff(a[:, 0]).astype(np.bool), 0, True)
columns_mask = np.insert(np.diff(a[0]).astype(np.bool), 0, True)
b = a[np.ix_(rows_mask, columns_mask)]
print " "
print "Subarray from Image:" #print as array
print " "
print b
#img = Image.fromarray(b, mode='L')
print " "
print "Subarray from Image (clearer format):" #print as array
print " "
for row in b: #print as a table like format
print(' '.join('{:3}'.format(value) for value in row))
#img.save("chocolate.png")
#print np.mean(b) #finding mean
例如此图片:
输入数组示例:
从a = list(img.getdata())
,这是我从图片中获得的输入。
[(115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (115, 45, 135), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (245, 245, 35), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (55, 235, 195), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95), (245, 245, 95)]
使用a = np.array ([a[offset:offset+WIDTH] for offset in range(0, WIDTH*HEIGHT, WIDTH)])
的numpy输入:
[[[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]]
[[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]]
[[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]]
[[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]]
[[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[115 45 135]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]
[245 245 35]]
[[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]]
[[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]]
[[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]]
[[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]]
[[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]]
[[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[ 55 235 195]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]
[245 245 95]]]
所需的输出:
[[[115 45 135] [245 245 35]]
[ 55 235 195] [245 245 95]]]
答案 0 :(得分:3)
这应该做到:
columns_mask = np.insert(np.any(np.any(np.diff(a, axis=0).astype(np.bool), axis=1), axis=1), 0, True)
rows_mask = np.insert(np.any(np.any(np.diff(a, axis=1).astype(np.bool), axis=0), axis=1), 0, True)
print(a[np.ix_(columns_mask, rows_mask)])
输出:
[[[115 45 135]
[245 245 35]]
[[ 55 235 195]
[245 245 95]]]
说明:
让我们举一个更具代表性的示例:
a = np.array([[[1, 2, 3],
[1, 2, 3],
[2, 4, 7],
[2, 4, 7],
[2, 4, 7]],
[[1, 2, 3],
[1, 2, 3],
[2, 4, 7],
[2, 4, 7],
[2, 4, 7]],
[[1, 2, 3],
[1, 2, 3],
[3, 4, 7],
[3, 4, 7],
[3, 4, 7]],
[[1, 2, 3],
[1, 2, 3],
[3, 4, 7],
[3, 4, 7],
[3, 4, 7]],
[[6, 4, 3],
[6, 4, 3],
[0, 1, 7],
[0, 1, 7],
[0, 1, 7]],
[[6, 4, 3],
[6, 4, 3],
[0, 1, 7],
[0, 1, 7],
[0, 1, 7]]])
我选择尺寸为6x5x3,以便于跟踪。
对于R,G和B,我们将具有以下子数组:
>>> print(a[:,:,0]) # R
[[1 1 2 2 2]
[1 1 2 2 2]
[1 1 3 3 3]
[1 1 3 3 3]
[6 6 0 0 0]
[6 6 0 0 0]]
>>> print(a[:,:,1]) # G
[[2 2 4 4 4]
[2 2 4 4 4]
[2 2 4 4 4]
[2 2 4 4 4]
[4 4 1 1 1]
[4 4 1 1 1]]
>>> print(a[:,:,2]) # B
[[3 3 7 7 7]
[3 3 7 7 7]
[3 3 7 7 7]
[3 3 7 7 7]
[3 3 7 7 7]
[3 3 7 7 7]]
请注意,在此示例中,我们有6种不同颜色的块。但是为了示例起见,对于某些组件,我选择了相同的值。
预期结果将是:
# R
[[1 2]
[1 3]
[6 0]]
# G
[[2 4]
[2 4]
[4 1]]
# B
[[3 7]
[3 7]
[3 7]]
首先,我们计算diff
以便找到颜色方块之间的边界。
对于列:
>>> print(np.diff(a, axis=0))
[[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[ 0 0 0]
[ 0 0 0]
[ 1 0 0]
[ 1 0 0]
[ 1 0 0]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[ 5 2 0]
[ 5 2 0]
[-3 -3 0]
[-3 -3 0]
[-3 -3 0]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]]
以及行:
>>> print(np.diff(a, axis=1))
[[[ 0 0 0]
[ 1 2 4]
[ 0 0 0]
[ 0 0 0]]
[[ 0 0 0]
[ 1 2 4]
[ 0 0 0]
[ 0 0 0]]
[[ 0 0 0]
[ 2 2 4]
[ 0 0 0]
[ 0 0 0]]
[[ 0 0 0]
[ 2 2 4]
[ 0 0 0]
[ 0 0 0]]
[[ 0 0 0]
[-6 -3 4]
[ 0 0 0]
[ 0 0 0]]
[[ 0 0 0]
[-6 -3 4]
[ 0 0 0]
[ 0 0 0]]]
仔细查看这些数字的来源。
接下来,我们使用.astype(np.bool)
将所有非零元素转换为True
。我们需要它来创建布尔掩码。有关使用布尔数组建立索引的更多信息,请参见NumPy docs。
对于列,我们得到:
>>> print(np.diff(a, axis=0).astype(np.bool))
[[[False False False]
[False False False]
[False False False]
[False False False]
[False False False]]
[[False False False]
[False False False]
[ True False False]
[ True False False]
[ True False False]]
[[False False False]
[False False False]
[False False False]
[False False False]
[False False False]]
[[ True True False]
[ True True False]
[ True True False]
[ True True False]
[ True True False]]
[[False False False]
[False False False]
[False False False]
[False False False]
[False False False]]]
对于行:
>>> print(np.diff(a, axis=1).astype(np.bool))
[[[False False False]
[ True True True]
[False False False]
[False False False]]
[[False False False]
[ True True True]
[False False False]
[False False False]]
[[False False False]
[ True True True]
[False False False]
[False False False]]
[[False False False]
[ True True True]
[False False False]
[False False False]]
[[False False False]
[ True True True]
[False False False]
[False False False]]
[[False False False]
[ True True True]
[False False False]
[False False False]]]
现在,我们应该在第一个数组的行之间和第二个数组的列之间应用逻辑或运算。我们需要这样做,以免丢失与例如R色具有相同值的连续块。
>>> print(np.any(np.diff(a, axis=0).astype(np.bool), axis=1))
[[False False False]
[ True False False]
[False False False]
[ True True False]
[False False False]]
>>> print(np.any(np.diff(a, axis=1).astype(np.bool), axis=0))
[[False False False]
[ True True True]
[False False False]
[False False False]]
有关np.any
的详细信息,请参见以下问题:How to operate logic operation of all columns of a 2D numpy array
。
现在,我们对颜色执行相同的操作:
>>> print(np.any(np.any(np.diff(a, axis=0).astype(np.bool), axis=1), axis=1))
[False True False True False]
>>> print(np.any(np.any(np.diff(a, axis=1).astype(np.bool), axis=0), axis=1))
[False True False False]
最后,使用np.insert
在数组的开头添加True
来考虑第一个元素:
>>> print(np.insert(np.any(np.any(np.diff(a, axis=0).astype(np.bool), axis=1), axis=1), 0, True))
[ True False True False True False]
>>> print(np.insert(np.any(np.any(np.diff(a, axis=1).astype(np.bool), axis=0), axis=1), 0, True))
[ True False True False False]
现在将这些索引与np.ix_
结合使用以获得所需的结果:
columns_mask = np.insert(np.any(np.any(np.diff(a, axis=0).astype(np.bool), axis=1), axis=1), 0, True)
rows_mask = np.insert(np.any(np.any(np.diff(a, axis=1).astype(np.bool), axis=0), axis=1), 0, True)
>>> print(a[np.ix_(columns_mask, rows_mask)])
[[[1 2 3]
[2 4 7]]
[[1 2 3]
[3 4 7]]
[[6 4 3]
[0 1 7]]]
就这样!
我们可以检查单独的颜色是否正确:
>>> print(a[np.ix_(columns_mask, rows_mask)][:, :, 0]) # R
[[1 2]
[1 3]
[6 0]]
>>> print(a[np.ix_(columns_mask, rows_mask)][:, :, 1]) # G
[[2 4]
[2 4]
[4 1]]
>>> print(a[np.ix_(columns_mask, rows_mask)][:, :, 2]) # B
[[3 7]
[3 7]
[3 7]]