如何从图像像素阵列创建平均rgb向量?

时间:2019-07-25 09:01:25

标签: python numpy python-imaging-library

我有一张图片,希望将其分解为30px x 30px的块。然后,我想对像素的r,g和b值进行平均。因此,例如,一个900像素乘900像素将分解为900个块(每个像素30像素乘30像素)。然后,我想取每个块中r,g和b值的平均值。最后,我想要一个由900个三维矢量组成的数组,每个矢量代表它们各自块的平均r,g,b值。

我曾尝试使用numpy和pillow来打破块,但似乎无法正确拼接像素阵列。

import numpy as np
from PIL import Image

item_image = Image.open("1.jpg")
pixel_array = np.asarray(item_image)
width, height = item_image.size
blocks = []

BLOCK_WIDTH = 30
BLOCK_HEIGHT = 30

row_start = 0
row_end = BLOCK_HEIGHT
column_start = 0
column_end = BLOCK_WIDTH
print(len(pixel_array))
while row_end < height:
  while column_end < width:
    row = slice(row_start, row_end)
    col = slice(column_start, column_end)
    blocks.append(pixel_array[ row , col ])
    column_start += BLOCK_WIDTH
    column_end += BLOCK_WIDTH
  row_start += BLOCK_HEIGHT
  row_end += BLOCK_HEIGHT

averaged_blocks = []

for i in range(BLOCK_HEIGHT):
  for j in range(BLOCK_WIDTH):
    averaged_blocks.append(np.mean(blocks[i][j], axis = 0))


我在处理图像方面还很陌生,所以如果有人有任何建议或建议,我将不胜感激!

4 个答案:

答案 0 :(得分:1)

如您所愿,我们可以通过一行 ImageMagick 满足您在shell中的要求,该行已安装在大多数Linux发行版中,并且可用于macOS和Windows。

>

因此,在shell或命令提示符下,拍摄一张图像,将其拆分为30x30的图块,通过将尺寸调整为1x1将每个图块的平均内容添加到新的单行图像中,并在显示时打印该图像的每个像素文本格式为8位:

magick image.png -crop 30x30 -resize 1x1\! +append -depth 8 txt:

示例输出

# ImageMagick pixel enumeration: 900,1,65535,rgb
0,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
1,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
2,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
3,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
4,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
5,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
6,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
7,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
8,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
9,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
10,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
11,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
12,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
13,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
14,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
15,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
16,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
17,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
18,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
19,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
20,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
21,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
22,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
23,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
24,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
25,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
26,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
27,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
28,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
29,0: (82.2696,63142.9,82.2696)  #00F600  rgb(0,246,0)
30,0: (254.322,58412.4,254.322)  #01E301  rgb(1,227,1)
31,0: (254.322,58412.4,254.322)  #01E301  rgb(1,227,1)
32,0: (254.322,58412.4,254.322)  #01E301  rgb(1,227,1)

答案 1 :(得分:1)

在Imagemagick中这很简单。您需要做的就是将图像缩小到30x30像素。比例尺将30x30个非重叠像素的块平均。 (或使用-filter框-resize代替-scale)。然后只需使用txt:输出格式列出结果图像的像素值即可。

创建900x900像素的水平渐变:

convert -size 900x900 gradient: -rotate 90 grad.png


enter image description here

缩放图像并列出每个像素:

 convert grad.png -scale 30x30 txt:

# ImageMagick pixel enumeration: 30,30,65535,gray

coords:  (16-bit rgb values) hex values   percent

0,0: (1057,0,64478)  #04210000FBDE  srgb(2%,0%,98%)
1,0: (3244,0,62291)  #0CAC0000F353  srgb(5%,0%,95%)
2,0: (5431,0,60104)  #15370000EAC8  srgb(8%,0%,92%)
3,0: (7618,0,57917)  #1DC20000E23D  srgb(12%,0%,88%)
4,0: (9805,0,55730)  #264D0000D9B2  srgb(15%,0%,85%)
5,0: (11992,0,53543)  #2ED80000D127  srgb(18%,0%,82%)
6,0: (14179,0,51356)  #37630000C89C  srgb(22%,0%,78%)
7,0: (16366,0,49169)  #3FEE0000C011  srgb(25%,0%,75%)
8,0: (18552,0,46983)  #48780000B787  srgb(28%,0%,72%)
9,0: (20739,0,44796)  #51030000AEFC  srgb(32%,0%,68%)
10,0: (22926,0,42609)  #598E0000A671  srgb(35%,0%,65%)
11,0: (25113,0,40422)  #621900009DE6  srgb(38%,0%,62%)
12,0: (27300,0,38235)  #6AA40000955B  srgb(42%,0%,58%)
13,0: (29487,0,36048)  #732F00008CD0  srgb(45%,0%,55%)
14,0: (31674,0,33861)  #7BBA00008445  srgb(48%,0%,52%)
15,0: (33861,0,31674)  #844500007BBA  srgb(52%,0%,48%)
16,0: (36048,0,29487)  #8CD00000732F  srgb(55%,0%,45%)
17,0: (38235,0,27300)  #955B00006AA4  srgb(58%,0%,42%)
18,0: (40422,0,25113)  #9DE600006219  srgb(62%,0%,38%)
19,0: (42609,0,22926)  #A6710000598E  srgb(65%,0%,35%)
20,0: (44796,0,20739)  #AEFC00005103  srgb(68%,0%,32%)
21,0: (46983,0,18552)  #B78700004878  srgb(72%,0%,28%)
22,0: (49169,0,16366)  #C01100003FEE  srgb(75%,0%,25%)
23,0: (51356,0,14179)  #C89C00003763  srgb(78%,0%,22%)
24,0: (53543,0,11992)  #D12700002ED8  srgb(82%,0%,18%)
25,0: (55730,0,9805)  #D9B20000264D  srgb(85%,0%,15%)
26,0: (57917,0,7618)  #E23D00001DC2  srgb(88%,0%,12%)
27,0: (60104,0,5431)  #EAC800001537  srgb(92%,0%,8%)
28,0: (62291,0,3244)  #F35300000CAC  srgb(95%,0%,5%)
29,0: (64478,0,1057)  #FBDE00000421  srgb(98%,0%,2%)
0,1: (1057,0,64478)  #04210000FBDE  srgb(2%,0%,98%)
1,1: (3244,0,62291)  #0CAC0000F353  srgb(5%,0%,95%)
2,1: (5431,0,60104)  #15370000EAC8  srgb(8%,0%,92%)
3,1: (7618,0,57917)  #1DC20000E23D  srgb(12%,0%,88%)
4,1: (9805,0,55730)  #264D0000D9B2  srgb(15%,0%,85%)
5,1: (11992,0,53543)  #2ED80000D127  srgb(18%,0%,82%)
6,1: (14179,0,51356)  #37630000C89C  srgb(22%,0%,78%)
7,1: (16366,0,49169)  #3FEE0000C011  srgb(25%,0%,75%)
8,1: (18552,0,46983)  #48780000B787  srgb(28%,0%,72%)
9,1: (20739,0,44796)  #51030000AEFC  srgb(32%,0%,68%)
10,1: (22926,0,42609)  #598E0000A671  srgb(35%,0%,65%)
11,1: (25113,0,40422)  #621900009DE6  srgb(38%,0%,62%)
12,1: (27300,0,38235)  #6AA40000955B  srgb(42%,0%,58%)
13,1: (29487,0,36048)  #732F00008CD0  srgb(45%,0%,55%)
14,1: (31674,0,33861)  #7BBA00008445  srgb(48%,0%,52%)
15,1: (33861,0,31674)  #844500007BBA  srgb(52%,0%,48%)
16,1: (36048,0,29487)  #8CD00000732F  srgb(55%,0%,45%)
17,1: (38235,0,27300)  #955B00006AA4  srgb(58%,0%,42%)
18,1: (40422,0,25113)  #9DE600006219  srgb(62%,0%,38%)
19,1: (42609,0,22926)  #A6710000598E  srgb(65%,0%,35%)
20,1: (44796,0,20739)  #AEFC00005103  srgb(68%,0%,32%)
21,1: (46983,0,18552)  #B78700004878  srgb(72%,0%,28%)
22,1: (49169,0,16366)  #C01100003FEE  srgb(75%,0%,25%)
23,1: (51356,0,14179)  #C89C00003763  srgb(78%,0%,22%)
24,1: (53543,0,11992)  #D12700002ED8  srgb(82%,0%,18%)
25,1: (55730,0,9805)  #D9B20000264D  srgb(85%,0%,15%)
26,1: (57917,0,7618)  #E23D00001DC2  srgb(88%,0%,12%)
27,1: (60104,0,5431)  #EAC800001537  srgb(92%,0%,8%)
28,1: (62291,0,3244)  #F35300000CAC  srgb(95%,0%,5%)
29,1: (64478,0,1057)  #FBDE00000421  srgb(98%,0%,2%)
.
.
.
0,28: (1057,0,64478)  #04210000FBDE  srgb(2%,0%,98%)
1,28: (3244,0,62291)  #0CAC0000F353  srgb(5%,0%,95%)
2,28: (5431,0,60104)  #15370000EAC8  srgb(8%,0%,92%)
3,28: (7618,0,57917)  #1DC20000E23D  srgb(12%,0%,88%)
4,28: (9805,0,55730)  #264D0000D9B2  srgb(15%,0%,85%)
5,28: (11992,0,53543)  #2ED80000D127  srgb(18%,0%,82%)
6,28: (14179,0,51356)  #37630000C89C  srgb(22%,0%,78%)
7,28: (16366,0,49169)  #3FEE0000C011  srgb(25%,0%,75%)
8,28: (18552,0,46983)  #48780000B787  srgb(28%,0%,72%)
9,28: (20739,0,44796)  #51030000AEFC  srgb(32%,0%,68%)
10,28: (22926,0,42609)  #598E0000A671  srgb(35%,0%,65%)
11,28: (25113,0,40422)  #621900009DE6  srgb(38%,0%,62%)
12,28: (27300,0,38235)  #6AA40000955B  srgb(42%,0%,58%)
13,28: (29487,0,36048)  #732F00008CD0  srgb(45%,0%,55%)
14,28: (31674,0,33861)  #7BBA00008445  srgb(48%,0%,52%)
15,28: (33861,0,31674)  #844500007BBA  srgb(52%,0%,48%)
16,28: (36048,0,29487)  #8CD00000732F  srgb(55%,0%,45%)
17,28: (38235,0,27300)  #955B00006AA4  srgb(58%,0%,42%)
18,28: (40422,0,25113)  #9DE600006219  srgb(62%,0%,38%)
19,28: (42609,0,22926)  #A6710000598E  srgb(65%,0%,35%)
20,28: (44796,0,20739)  #AEFC00005103  srgb(68%,0%,32%)
21,28: (46983,0,18552)  #B78700004878  srgb(72%,0%,28%)
22,28: (49169,0,16366)  #C01100003FEE  srgb(75%,0%,25%)
23,28: (51356,0,14179)  #C89C00003763  srgb(78%,0%,22%)
24,28: (53543,0,11992)  #D12700002ED8  srgb(82%,0%,18%)
25,28: (55730,0,9805)  #D9B20000264D  srgb(85%,0%,15%)
26,28: (57917,0,7618)  #E23D00001DC2  srgb(88%,0%,12%)
27,28: (60104,0,5431)  #EAC800001537  srgb(92%,0%,8%)
28,28: (62291,0,3244)  #F35300000CAC  srgb(95%,0%,5%)
29,28: (64478,0,1057)  #FBDE00000421  srgb(98%,0%,2%)
0,29: (1057,0,64478)  #04210000FBDE  srgb(2%,0%,98%)
1,29: (3244,0,62291)  #0CAC0000F353  srgb(5%,0%,95%)
2,29: (5431,0,60104)  #15370000EAC8  srgb(8%,0%,92%)
3,29: (7618,0,57917)  #1DC20000E23D  srgb(12%,0%,88%)
4,29: (9805,0,55730)  #264D0000D9B2  srgb(15%,0%,85%)
5,29: (11992,0,53543)  #2ED80000D127  srgb(18%,0%,82%)
6,29: (14179,0,51356)  #37630000C89C  srgb(22%,0%,78%)
7,29: (16366,0,49169)  #3FEE0000C011  srgb(25%,0%,75%)
8,29: (18552,0,46983)  #48780000B787  srgb(28%,0%,72%)
9,29: (20739,0,44796)  #51030000AEFC  srgb(32%,0%,68%)
10,29: (22926,0,42609)  #598E0000A671  srgb(35%,0%,65%)
11,29: (25113,0,40422)  #621900009DE6  srgb(38%,0%,62%)
12,29: (27300,0,38235)  #6AA40000955B  srgb(42%,0%,58%)
13,29: (29487,0,36048)  #732F00008CD0  srgb(45%,0%,55%)
14,29: (31674,0,33861)  #7BBA00008445  srgb(48%,0%,52%)
15,29: (33861,0,31674)  #844500007BBA  srgb(52%,0%,48%)
16,29: (36048,0,29487)  #8CD00000732F  srgb(55%,0%,45%)
17,29: (38235,0,27300)  #955B00006AA4  srgb(58%,0%,42%)
18,29: (40422,0,25113)  #9DE600006219  srgb(62%,0%,38%)
19,29: (42609,0,22926)  #A6710000598E  srgb(65%,0%,35%)
20,29: (44796,0,20739)  #AEFC00005103  srgb(68%,0%,32%)
21,29: (46983,0,18552)  #B78700004878  srgb(72%,0%,28%)
22,29: (49169,0,16366)  #C01100003FEE  srgb(75%,0%,25%)
23,29: (51356,0,14179)  #C89C00003763  srgb(78%,0%,22%)
24,29: (53543,0,11992)  #D12700002ED8  srgb(82%,0%,18%)
25,29: (55730,0,9805)  #D9B20000264D  srgb(85%,0%,15%)
26,29: (57917,0,7618)  #E23D00001DC2  srgb(88%,0%,12%)
27,29: (60104,0,5431)  #EAC800001537  srgb(92%,0%,8%)
28,29: (62291,0,3244)  #F35300000CAC  srgb(95%,0%,5%)
29,29: (64478,0,1057)  #FBDE00000421  srgb(98%,0%,2%)

答案 2 :(得分:1)

通常,您要避免在周围复制大图像或图像块,因为它比较慢。通常最好随行进行处理,而不是构建新的数据结构以供以后处理。

因此,请牢记:

#!/usr/bin/env python3

from PIL import Image
import numpy as np

BLKSIZE=30

# Load image into Numpy array
im = np.array(Image.open('image.png').convert('RGB'))

for y in range(0, 900, BLKSIZE):
    for x in range(0, 900, BLKSIZE):
        view = im[y:y+BLKSIZE, x:x+BLKSIZE]
        Rmean = np.mean(view[...,0]) 
        Gmean = np.mean(view[...,1]) 
        Bmean = np.mean(view[...,2]) 
        print(f'Block {y},{x}, R:{Rmean:.2f}, G:{Gmean:.2f}, B:{Bmean:.2f}') 

示例输出-使用Fred的图像(@ fmw42)

Block 0,0, R:4.13, G:4.13, B:4.13
Block 0,30, R:12.60, G:12.60, B:12.60
Block 0,60, R:21.13, G:21.13, B:21.13
Block 0,90, R:29.63, G:29.63, B:29.63
Block 0,120, R:38.13, G:38.13, B:38.13
Block 0,150, R:46.70, G:46.70, B:46.70
Block 0,180, R:55.13, G:55.13, B:55.13
Block 0,210, R:63.73, G:63.73, B:63.73
Block 0,240, R:72.13, G:72.13, B:72.13
Block 0,270, R:80.73, G:80.73, B:80.73
Block 0,300, R:89.17, G:89.17, B:89.17
Block 0,330, R:97.73, G:97.73, B:97.73
Block 0,360, R:106.23, G:106.23, B:106.23
Block 0,390, R:114.73, G:114.73, B:114.73
Block 0,420, R:123.27, G:123.27, B:123.27
Block 0,450, R:131.73, G:131.73, B:131.73
Block 0,480, R:140.27, G:140.27, B:140.27
Block 0,510, R:148.77, G:148.77, B:148.77
Block 0,540, R:157.27, G:157.27, B:157.27
Block 0,570, R:165.83, G:165.83, B:165.83
Block 0,600, R:174.27, G:174.27, B:174.27
Block 0,630, R:182.87, G:182.87, B:182.87
Block 0,660, R:191.27, G:191.27, B:191.27
Block 0,690, R:199.87, G:199.87, B:199.87
Block 0,720, R:208.30, G:208.30, B:208.30
Block 0,750, R:216.87, G:216.87, B:216.87
Block 0,780, R:225.37, G:225.37, B:225.37
Block 0,810, R:233.87, G:233.87, B:233.87
Block 0,840, R:242.40, G:242.40, B:242.40
Block 0,870, R:250.87, G:250.87, B:250.87
Block 30,0, R:4.13, G:4.13, B:4.13
Block 30,30, R:12.60, G:12.60, B:12.60
Block 30,60, R:21.13, G:21.13, B:21.13
...
...
Block 870,750, R:216.87, G:216.87, B:216.87
Block 870,780, R:225.37, G:225.37, B:225.37
Block 870,810, R:233.87, G:233.87, B:233.87
Block 870,840, R:242.40, G:242.40, B:242.40
Block 870,870, R:250.87, G:250.87, B:250.87

答案 3 :(得分:0)

row_start和row_end变量存在逻辑错误。您不需要使用2个变量作为开始和结束。

请使用以下代码,并替换为while循环。

blocks=[]
while(row_start < height):
col_start = 0
    while(col_start < width):
        patch = pixel_array[row_start:row_start+30,col_start:col_start+30]
        #print(patch.shape)
        blocks.append(patch)
        col_start+=30
        #print(row_start,col_start)
row_start+=30

现在,块数组将具有大小为30、30、3的900个补丁。我已经硬编码了值30,以提取补丁。根据使用情况更改值以使其动态。