通过映射缩小图像尺寸

时间:2018-10-16 18:24:10

标签: python arrays numpy

我有一个带有四种颜色的.png图像。如果将图像转换为numpy数组,则会得到具有以下尺寸的数组:[length X height X 3],带有length == height。 如何通过映射颜色来缩小尺寸?

这是当前结构:

array([[[  0,  65, 101],
    [  0,  65, 101],
    [  0,  65, 101],
    ...,
    [  0,  65, 101],
    [  0,  65, 101],
    [  0,  65, 101]],

   [[  0,  65, 101],
    [163, 219, 232],
    [163, 219, 232],
    ...,
    [  0,  65, 101],
    [163, 219, 232],
    [  0,  65, 101]],

   [[  0,  65, 101],
    [163, 219, 232],
    [  0,  65, 101],
    ...,
    [  0,  65, 101],
    [163, 219, 232],
    [  0,  65, 101]],

   ...,

   [[  0,  65, 101],
    [163, 219, 232],
    [  0,  65, 101],
    ...,
    [  0,  65, 101],
    [  0,  65, 101],
    [  0,  65, 101]],

   [[  0,  65, 101],
    [163, 219, 232],
    [163, 219, 232],
    ...,
    [163, 219, 232],
    [163, 219, 232],
    [  0,  65, 101]],

   [[  0,  65, 101],
    [  0,  65, 101],
    [  0,  65, 101],
    ...,
    [  0,  65, 101],
    [  0,  65, 101],
    [  0,  65, 101]]], dtype=uint8)  

我想要一个二维数组,i'th行和j'th列中的每个值都将对应于三维中的颜色。因此,如果原始图像的尺寸为7 X 7 X 3,有四种颜色,则输出将如下所示:

array([[0, 1, 1, 3, 3, 3, 0],
   [0, 2, 1, 1, 1, 1, 0],
   [0, 2, 0, 1, 2, 1, 0],
   [0, 3, 1, 1, 3, 1, 0],
   [0, 1, 0, 0, 3, 0, 0],
   [0, 1, 1, 1, 1, 1, 0],
   [0, 0, 0, 0, 0, 0, 0]])

前面提到的数组中的值都是伪造的,所以它们彼此不对应,我只是尝试表示这个概念。

我将图片读取为:

from PIL import Image
import numpy as np

img = Image.open('image.png')
imgarray = np.asarray(img)

print(imgarray)

1 个答案:

答案 0 :(得分:1)

您可以为此使用numpy.unique。例如,这是一个3x5图像,只有三种颜色:

In [105]: img
Out[105]: 
array([[[10, 20, 30],
        [ 5,  5,  0],
        [ 5,  5,  0],
        [ 5,  5,  0],
        [ 0,  0,  0]],

       [[ 5,  5,  0],
        [ 5,  5,  0],
        [ 0,  0,  0],
        [ 0,  0,  0],
        [ 0,  0,  0]],

       [[10, 20, 30],
        [10, 20, 30],
        [10, 20, 30],
        [10, 20, 30],
        [ 5,  5,  0]]])

在整形后的图像上调用numpy.unique。将前两个维展平为一个维,然后使用axis=0,以便获得唯一的颜色。 inv将保存“逆”数组,即原始值colors的索引。

In [106]: colors, inv = np.unique(img.reshape(-1, 3), axis=0, return_inverse=True)

In [107]: colors
Out[107]: 
array([[ 0,  0,  0],
       [ 5,  5,  0],
       [10, 20, 30]])

In [108]: inv
Out[108]: array([2, 1, 1, 1, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 1])

重新整形inv,使索引数组以与原始图像相同的形状进入colors

In [109]: inv.reshape(img.shape[:2])
Out[109]: 
array([[2, 1, 1, 1, 0],
       [1, 1, 0, 0, 0],
       [2, 2, 2, 2, 1]])