Reducir la dimensión de la imagen con mapeo

Tengo una imagen .png con cuatro colores en ella. Si convierto la imagen a una matriz numpy obtengo una matriz con las siguientes dimensiones: [length X height X 3] , con length == height . ¿Cómo puedo reducir la dimensión con el mapeo de los colores?

Esta es la estructura actual:

 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) 

Y me gustaría una matriz con dos dimensiones, y cada valor en la fila i'th y i'th se correspondería con el color que tenía en la tercera dimensión. Entonces, si la imagen original tuviera 7 X 7 X 3 dimensión de 7 X 7 X 3 con cuatro colores, la salida sería algo como esto:

 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]]) 

Los valores en los arreglos mencionados están todos creados, por lo que no se corresponden entre sí, solo traté de representar el concepto.

Leí la foto como:

 from PIL import Image import numpy as np img = Image.open('image.png') imgarray = np.asarray(img) print(imgarray) 

Puedes usar numpy.unique para esto. Por ejemplo, aquí hay una imagen de 3×5 que tiene solo tres colores:

 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]]]) 

Llame a numpy.unique en la imagen remodelada. Las dos primeras dimensiones se aplanan en una sola dimensión, y luego se usa el axis=0 para obtener los colores únicos. inv tendrá la matriz de “inversos”, es decir, los índices en colors de los valores originales.

 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]) 

Remodela inv para obtener la matriz de índices en colors con la misma forma que la imagen original:

 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]])