0% encontró este documento útil (0 votos)
30 vistas19 páginas

Funciones de Procesamiento de Imágenes

Este documento presenta funciones para reducir la cantidad de colores en una imagen mediante cuantización de color. Se definen funciones para medir la distancia entre colores, obtener una muestra de colores de una imagen, sustituir los colores de una imagen por los colores más cercanos en una lista de colores, y obtener los colores más representativos de una imagen mediante iteraciones que actualizan la lista de colores. El documento prueba estas funciones en una imagen de playa.

Cargado por

Miguel Uribe
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
30 vistas19 páginas

Funciones de Procesamiento de Imágenes

Este documento presenta funciones para reducir la cantidad de colores en una imagen mediante cuantización de color. Se definen funciones para medir la distancia entre colores, obtener una muestra de colores de una imagen, sustituir los colores de una imagen por los colores más cercanos en una lista de colores, y obtener los colores más representativos de una imagen mediante iteraciones que actualizan la lista de colores. El documento prueba estas funciones en una imagen de playa.

Cargado por

Miguel Uribe
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

# Miguel Uribe Pérez-Luque, M3, Práctica 3

from imagen import *


from typing import Callable,Union

# Importamos el módulo imagen y los tipos Callable y Union del módulo


typing.

# Las siguientes funciones vienen dadas en la práctica

def dist1(color1:Color,color2:Color):
result = 0
for i in range(len(color1)):
result = result + (color1[i]-color2[i])**2
return result
def dist2(color1:Color,color2:Color)->int:
result = 0
for i in range(len(color1)):
result = max(result, abs(color1[i]-color2[i]))
return result
def dist3(color1:Color,color2:Color)->int:
result = 0
cofs = [2, 4, 3]
for i in range(len(color1)):
result = result + cofs[i]*(color1[i]-color2[i])**2
return result
def muestra(img:ImagenColor,k:int,l:int)->list[Color]:
width,heigth = len(img[0]), len(img)
result = []
for y in range(0,heigth,heigth//k):
for x in range(0,width,width//l):
result.append(img[y][x])
return result

# Además, nos ayudaremos de una función para optimizar nuestras


funciones: min_index

def min_index (color: Color, color_list: list[Color], distance:


Callable[[Color,Color],int]) -> int:

# Definimos la función min_index que toma:


# - un color base de tipo Color
# - una lista de colores color_list de tipo list[Color]
# - una función distance de tipo Callable (que mide la distancia
entre dos colores)

# La función devuelve el índice de color_list cuya distancia al


color base es la mínima de todas ellas
# El código es el siguiente:
# Creamos las dos variables a devolver, min_dist e index
# Damos como valor a min_dist como la distancia al primer color de
la lista, y el índice comienza siendo 0

min_dist = distance(color,color_list[0])

index = 0

# Vemos en un bucle sencillo cuál es el valor mínimo de las


distancias
# En caso de ser una distancia menor a la inicial, sustituimos el
valor de min_dist y el índice
# Como ya hemos asignado el primer elemento de color_list a una
distancia, no lo tenemos en cuenta (empezamos desde el índice 1)

for i in range (len(color_list)-1):

if distance(color,color_list[i+1]) < min_dist:

min_dist = distance(color,color_list[i+1])

index = i+1

# Una vez terminado el bucle, tenemos que min_dist es la distancia


mínima y que index es el índice que buscamos

return index

# Ahora pasamos a las funciones de la práctica

def img_subst (img: ImagenColor, color_list: list[Color], distance:


Callable[[Color,Color],int]) -> ImagenColor:

# Definimos la función img_subst que toma:


# - una imagen img de tipo ImagenColor
# - una lista de colores color_list de tipo list[Color]
# - una función distance de tipo Callable (que mide la distancia
entre dos colores)

# La función devuelve una imagen aproximada de img acorde a los


colores de color_list, de tipo ImagenColor.
# El código es el siguiente:

# Creamos new_img, que contendrá la nueva imagen

new_img = []

# Analizamos cada fila de colores de la imagen original para crear


nuestra nueva imagen

for row in img:

# Por cada fila creamos una lista new_row

new_row = []

# Recorremos cada color en la fila original y vemos qué color


de la paleta es el más cercano, para crear las filas nuevas

for color in row:

# Añadimos el color más cercano de nuestra paleta a


new_row, ayudándonos de min_index

new_row.append(color_list[min_index(color, color_list,
distance)])

# Añadimos la fila nueva creada a new_img

new_img.append(new_row)

# Así, finalmente queda una new_img de tipo ImagenColor, que es


una imagen con los colores aproximados a los de color_list

# La función nos devuelve la imagen nueva new_img

return new_img

# Pasamos ahora a la función auxiliar de la que nos ayudamos para


colores_mas_representativos

def new_list (img: ImagenColor, color_list: list[Color], distance:


Callable[[Color,Color],int]) -> list[Color]:

# Definimos la función new_list que toma:


# - una imagen img de tipo ImagenColor
# - una lista de colores color_list de tipo list[Color]
# - una función distance de tipo Callable (que mide la distancia
entre dos colores)

# La función devuelve una nueva lista de colores más aproximada a


los colores de img, de tipo list[Color]
# El código es el siguiente:

# Creamos la lista vacía new_colors, que será la lista que


acabamos de mencionar
new_colors = []

# Creamos la lista close_colors


# Esta lista va a almacenar los grupos de colores de la imagen
similares a cada color de color_list y el número de colores en cada
uno
# Los primeros tres 0 de cada lista corresponderán a los valores
RGB y el último al número de colores añadidos al grupo

close_colors = [[0,0,0,0] for color in color_list]

# Para optimizar, creamos una variable que tenga la longitud de


color_list

len_color_list = len(color_list)

# Metemos cada color de la imagen img en el grupo correspondiente,


acorde a la cercanía con los colores de color_list

for img_row in img:

for img_color in img_row:

# Sumamos el color (valores en RGB) img_color al grupo de


close_colors con índice igual al de la distancia mínima (el color de
color_list más cercano)
# Nos ayudamos de min_index para meter el color de la
imagen en el grupo cercano

index_close_color = min_index(img_color, color_list,


distance)

# Creamos el bucle para sumar los valores RGB

for i in range (3):

close_colors[index_close_color][i] += img_color[i]

close_colors[index_close_color][3] += 1

# Una vez clasificados todos los colores por grupos, añadimos a


new_colors un color nuevo por cada grupo (por cada color de
color_list)

for i in range (len_color_list):

# Creamos nuestro color new_color al que le vamos a sumar la


media de colores por cada grupo
new_color = [0,0,0]

# Creamos el bucle para sumar las medias

for j in range (3):

# Por cada valor RGB sumamos la media de los colores


cercanos del grupo que corresponda con división entera
# Si no han habido colores en ese grupo, será división por
cero, por lo que usamos try/except

try:

new_color[j] += round(close_colors[i]
[j]/close_colors[i][3])

except:

# Si no hay colores en el grupo, dejamos el color como


estaba, pues no se tendrá en cuenta en img_subst
# (recordemos que esa función tiene en cuenta los
colores cercanos, pero color_list[i] no es cercano a ninguno de img)

new_color[j] += color_list[i]

# Añadimos el color a la lista que queremos obtener

new_colors.append(new_color)

# La función nos devuelve la lista que estábamos buscando

return new_colors

# Ahora, la última función de la práctica (la más importante)

def colores_mas_representativos (img: ImagenColor,color_list:


list[Color], distance: Callable[[Color,Color],int]) -> list[Color]:

# Definimos la función colores_mas_representativos que toma:


# - una imagen img de tipo ImagenColor
# - una lista de colores color_list de tipo list[Color]
# - una función distance de tipo Callable (que mide la distancia
entre dos colores)

# La función devuelve una lista de los colores más representativos


de img, aproximados con color_list, de tipo list[Color]
# Consiste básicamente en repetir new_list hasta que las listas de
colores creadas sean prácticamente iguales (recordemos que new_list
tiende a estabilizarse)
# El código es el siguiente:

# Creamos una nueva lista new_colors que surge de aplicar new_list


a color_list (con img y distance)
# Esta lista es la que vamos a comparar con color_list para ver
cuándo detenemos las repeticiones de new_list

new_colors = new_list(img, color_list, distance)

# Creamos un contador de iteraciones para verificar que son las


mismas que indica la práctica

iteraciones = 0

# Creamos un bucle para que se repita el proceso hasta que


color_list y new_colors sean iguales

while True:

# Sumamos uno al contador de iteraciones

iteraciones += 1

# Cambiamos color_list por una copia de new_colors

color_list = new_colors.copy()

# Repetimos new_list con new_colors

new_colors = new_list(img, new_colors, distance)

# Una vez que color_list sea igual a new_colors, detenemos el


bucle

if color_list == new_colors:

break

# Si no ha terminado el bucle, se repetirá new_list

# Una vez acabado el bucle, la función nos devuelve new_colors,


que es la lista de colores que buscábamos
# También mostramos el número de iteraciones

print(f" - Obtenidos los colores más representativos en


{iteraciones} iteraciones")

return new_colors
# Fin de la práctica

#______________________________________________________________

# Ahora realizamos las pruebas de la práctica:

# La ruta del archivo depende del ordenador


img = read("C:/beach.jpg")
show(img)

# Realizamos las pruebas de img_subst con muestra(img,4,2)


colors_list = muestra(img,4,2)

conv = img_subst(img,colors_list,dist1)
show(conv)
conv1 = img_subst(img,colors_list,dist2)
show(conv1)
conv2 = img_subst(img,colors_list,dist3)
show(conv2)
# Ahora probamos las de colores_mas_representativos, primero con
muestra(img,5,3)
colors_list = muestra(img,5,3)

l1 = colores_mas_representativos(img,colors_list,dist1)
show(img_subst(img,l1,dist1))

- Obtenidos los colores más representativos en 36 iteraciones


l2 = colores_mas_representativos(img,colors_list,dist2)
show(img_subst(img,l2,dist2))

- Obtenidos los colores más representativos en 52 iteraciones


l3 = colores_mas_representativos(img,colors_list,dist3)
show(img_subst(img,l3,dist3))

- Obtenidos los colores más representativos en 51 iteraciones


# Ahora con colores primarios
colors_list1 = [[255,0,0],[0,255,0],[0,0,255]]

l4 = colores_mas_representativos(img,colors_list1,dist1)
show(img_subst(img,l4,dist1))

- Obtenidos los colores más representativos en 14 iteraciones


l5 = colores_mas_representativos(img,colors_list1,dist2)
show(img_subst(img,l5,dist2))

- Obtenidos los colores más representativos en 13 iteraciones


l6 = colores_mas_representativos(img,colors_list1,dist3)
show(img_subst(img,l6,dist3))

- Obtenidos los colores más representativos en 10 iteraciones


# Por último con muestra(img,2,2)
colors_list2 = muestra(img,2,2)

l7 = colores_mas_representativos(img,colors_list2,dist1)
show(img_subst(img,l7,dist1))

- Obtenidos los colores más representativos en 7 iteraciones


l8 = colores_mas_representativos(img,colors_list2,dist2)
show(img_subst(img,l8,dist2))

- Obtenidos los colores más representativos en 8 iteraciones


l9 = colores_mas_representativos(img,colors_list2,dist3)
show(img_subst(img,l9,dist3))

- Obtenidos los colores más representativos en 8 iteraciones

También podría gustarte