首页 > 解决方案 > 通过映射减少图像维度

问题描述

我有一个 .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)

标签: pythonarraysnumpy

解决方案


你可以用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]])

推荐阅读