0% encontró este documento útil (0 votos)
6 vistas8 páginas

HILOGRAMA

El documento explica detalladamente un script de hilograma que utiliza varias librerías para procesar imágenes y generar arte con hilos. Se describen las funciones clave, como la selección de imágenes, el preprocesamiento, la generación de clavos y la aplicación de líneas, así como el algoritmo general que controla el proceso. Además, se abordan aspectos como la mejora de la imagen, el cálculo físico y la visualización del resultado final.

Cargado por

domi034crazypoet
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 DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
6 vistas8 páginas

HILOGRAMA

El documento explica detalladamente un script de hilograma que utiliza varias librerías para procesar imágenes y generar arte con hilos. Se describen las funciones clave, como la selección de imágenes, el preprocesamiento, la generación de clavos y la aplicación de líneas, así como el algoritmo general que controla el proceso. Además, se abordan aspectos como la mejora de la imagen, el cálculo físico y la visualización del resultado final.

Cargado por

domi034crazypoet
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 DOCX, PDF, TXT o lee en línea desde Scribd

¡Perfecto!

A continuación te explico cada línea de código de tu script de hilograma paso a paso,


con un nivel de detalle apto para exposición universitaria 👩🏻‍🏫.
Está organizado por bloques funcionales, y cada línea tiene su explicación directa.

🧩 1. Importación de librerías
import cv2

→ Importa OpenCV, usada para leer imágenes y convertirlas en escala de grises, así como
para redimensionarlas.

import numpy as np

→ Importa NumPy, necesario para trabajar con matrices numéricas, como imágenes en escala
de grises.

from PIL import Image

→ Importa el módulo de Pillow para guardar imágenes en formato PNG o visualizar


resultados.

import [Link] as plt

→ Permite mostrar imágenes en pantalla, como resultado final.

import tkinter as tk
from tkinter import filedialog

→ Se usa tkinter para abrir una ventana emergente donde el usuario elige una imagen.

import math

→ Para usar funciones trigonométricas (seno, coseno) al generar las posiciones de los clavos en
un círculo.

import random

→ Permite seleccionar algunos clavos aleatorios y evitar que el algoritmo quede atascado en
mínimos locales.

 Permite seleccionar elementos al azar. En tu caso, clavos alejados se eligen


aleatoriamente para mejorar el arte.

 Sin random, se perdería la exploración lejana: solo se conectarían clavos vecinos,


resultando en imágenes aburridas o ineficaces.
Pero hay MUCHOS clavos (¡3000!) y sería muy lento mirar todos uno por uno. Así que el
programa dice:

“Voy a mirar los clavos cerquita del que usé antes… pero también voy a elegir unos pocos al
azar, usando random, para ver si alguno me da una mejor línea.”

🔍 Esto ayuda al programa a no quedarse atrapado solo en los vecinos cercanos y explorar líneas
locas que cruzan el círculo, como una telaraña artística.

❌ ¿Y si NO usamos random?

 El programa sería muy aburrido 😴.


 Solo probaría los clavos cercanos.
 No haría líneas divertidas que pasan por el centro.
 La imagen se parecería menos a la original.

🖼️Función seleccionar_imagen():

Esta función es como decirle a la computadora:


“Haz que aparezca una ventanita, para que el usuario pueda elegir una imagen del
computador.”
Como si estuvieras diciendo: “¡Elige tu dibujo favorito para jugar con él!”

🧩 Paso a paso, como en una historia:

root = [Link]()

👶 “Primero, le decimos a la computadora que haga una ventana mágica (root).”


Es como abrir una caja para mostrar algo, pero no le hemos dicho qué todavía.

[Link]()

🫣 “Ups... ¡No queremos que se vea esa ventana fea! Así que la escondemos.”
Solo queremos usar la ventanita que pide el archivo, no toda la aplicación.

[Link]("-topmost", True)

🧲 “Le pedimos que la ventanita que viene esté en la parte de arriba, para que el usuario la vea.”
Así no queda tapada por otras ventanas, como cuando pones tu dibujo encima de todos los
papeles.

file_path = [Link]( title="Selecciona la imagen", filetypes=[("Imágenes",


"*.jpg *.jpeg *.png *.bmp")] )
🎨 “Ahora sí, aparece la ventanita para que elijas tu imagen favorita.”
El usuario puede buscar en sus carpetas y hacer clic en una imagen.
📁 Solo acepta imágenes con terminaciones .jpg, .jpeg, .png, .bmp.

[Link]()

🧹 “¡Listo! Cerramos y limpiamos la ventana que habíamos creado al principio.”


Como decirle: “Gracias, ya no te necesito.”

return file_path

📬 “Le damos al programa la dirección donde está guardada la imagen que elegimos.”
Es como decir: “Aquí está el dibujo, ahora úsalo para crear arte con hilos.”

⚙️3. Preprocesamiento de la imagen


def preprocesar_imagen(path, size=400):

→ Define una función que carga, redimensiona y normaliza una imagen.

img = [Link](path, cv2.IMREAD_GRAYSCALE)

→ Carga la imagen en escala de grises usando OpenCV.

if img is None:
raise FileNotFoundError(f"No se pudo cargar la imagen: {path}")

→ Verifica que la imagen se haya cargado correctamente.

img = [Link](img, (size, size), interpolation=cv2.INTER_AREA)

→ Redimensiona la imagen a 400x400 píxeles.

target = 1.0 - (img / 255.0)

→ Convierte los valores de 0-255 a 0.0-1.0 e invierte (negro = 1.0 = se necesita hilo).

return target

→ Devuelve la imagen procesada.

🔩 4. Generar coordenadas de los clavos


def generar_clavos(n, radio, centro):
→ Define una función que genera n puntos en un círculo.

cx, cy = centro

→ Extrae las coordenadas del centro del círculo.

return [
(int(cx + radio * [Link](2 * [Link] * i / n)),
int(cy + radio * [Link](2 * [Link] * i / n)))
for i in range(n)
]

→ Calcula las coordenadas (x, y) de cada clavo usando funciones trigonométricas.

🧮 5. Algoritmo de Bresenham (línea de pixeles)


def bresenham(p1, p2):

→ Define la función para obtener los píxeles entre dos puntos.

x0, y0 = p1
x1, y1 = p2

→ Extrae coordenadas de los extremos de la línea.

puntos = []

→ Inicializa la lista de puntos.

dx = abs(x1 - x0)
dy = abs(y1 - y0)

→ Calcula diferencias en X y Y.

sx = 1 if x0 < x1 else -1
sy = 1 if y0 < y1 else -1

→ Define la dirección del paso.

err = dx - dy

→ Inicializa el error de la línea.

while True:
[Link]((x0, y0))
if x0 == x1 and y0 == y1:
break
→ Agrega el punto actual y detiene cuando se alcanza el final.

e2 = 2 * err
if e2 > -dy:
err -= dy
x0 += sx
if e2 < dx:
err += dx
y0 += sy

→ Ajusta el error y avanza el punto actual.

return puntos

→ Devuelve los puntos de la línea.

📈 6. Evaluar mejora
def evaluar_mejora(target, current, linea):

→ Calcula cuánto mejora la imagen si se aplica una línea.

mejora = 0.0

→ Inicializa el valor de mejora.

for x, y in linea:
if 0 <= x < [Link][1] and 0 <= y < [Link][0]:
diff = target[y, x] - current[y, x]
if diff > 0:
mejora += diff

→ Suma las diferencias positivas entre target y current.

return mejora

→ Devuelve el valor total de mejora.

🖊️7. Aplicar una línea al canvas actual


def aplicar_linea(current, linea, incremento=0.08):

→ Aplica una línea sumando intensidad.


for x, y in linea:
if 0 <= x < [Link][1] and 0 <= y < [Link][0]:
current[y, x] = min(1.0, current[y, x] + incremento)

→ Suma un pequeño valor al píxel (sin pasarse de 1).

🔁 8. Algoritmo general del hilograma


def generar_string_art(path, n_clavos=3000, max_lineas=4000,
diametro_real_mm=200, vecinos=150, aleatorios=100):

→ Función principal. Controla todo el proceso.

size = 400
radio_pix = size // 2 - 5
centro = (size // 2, size // 2)

→ Define el tamaño del lienzo y del círculo de clavos.

target = preprocesar_imagen(path, size)


current = np.zeros_like(target, dtype=float)

→ Carga la imagen y crea una copia vacía (current).

clavos = generar_clavos(n_clavos, radio_pix, centro)

→ Calcula las posiciones de los clavos.

secuencia = []
indice_actual = 0

→ Inicializa la secuencia de pasos y el punto inicial.

for paso in range(max_lineas):

→ Repite hasta max_lineas veces:

mejor_mejora = -1
mejor_indice = None
mejor_linea = None

→ Inicializa variables para guardar la mejor opción.

vecinos_cercanos = [(indice_actual + i) % n_clavos for i in range(1,


vecinos + 1)] + \
[(indice_actual - i) % n_clavos for i in range(1,
vecinos + 1)]
→ Selecciona clavos cercanos.

candidatos_posibles = [i for i in range(n_clavos) if i !=


indice_actual and i not in vecinos_cercanos]
vecinos_aleatorios = [Link](candidatos_posibles, aleatorios) if
len(candidatos_posibles) >= aleatorios else candidatos_posibles

→ Selecciona clavos aleatorios para evitar ciclos.

candidatos = vecinos_cercanos + vecinos_aleatorios

→ Junta todos los posibles clavos candidatos.

for i in candidatos:
linea = bresenham(clavos[indice_actual], clavos[i])
mejora = evaluar_mejora(target, current, linea)
if mejora > mejor_mejora:
mejor_mejora = mejora
mejor_indice = i
mejor_linea = linea

→ Revisa cuál línea mejora más la imagen.

if mejor_mejora <= 0:
break

→ Si no mejora más, termina.

aplicar_linea(current, mejor_linea, incremento=0.08)


[Link]((indice_actual, mejor_indice))
indice_actual = mejor_indice

→ Aplica la línea y actualiza la secuencia.

📏 9. Cálculo físico
perimetro = [Link] * diametro_real_mm
distancia_entre_clavos = perimetro / n_clavos

→ Calcula distancia real entre clavos (en mm).

💾 10. Guardar resultados


imagen_final = [Link](np.uint8(255 * (1 - current)), mode='L')
imagen_final.save("[Link]")
→ Guarda la imagen final como PNG.

with open("[Link]", "w") as f:


for i, j in secuencia:
[Link](f"{i} -> {j}\n")

→ Guarda los pasos en un archivo de texto.

👁️11. Mostrar imagen final


[Link](imagen_final, cmap='gray')
[Link]('off')
[Link]()

→ Muestra la imagen generada en blanco y negro.

🚀 12. Ejecutar todo el programa


if __name__ == "__main__":
...

→ Bloque que solo se ejecuta si el archivo se corre directamente.

try:
ruta = seleccionar_imagen()
if ruta:
generar_string_art(ruta)
else:
print("No seleccionaste ninguna imagen.")
except Exception as e:
print("Error:", e)

→ Pide la imagen, ejecuta todo, y muestra error si ocurre algo mal.

¿Quieres ahora una versión lista para imprimir o para mostrar tipo PowerPoint? ¿O seguimos con
las preguntas y respuestas para defensa oral?

También podría gustarte