¿Qué es una imagen digital?

Una imagen digital es una matriz de píxeles que representan información visual.

Ejemplo: crear una imagen negra de 100x100 píxeles en NumPy.

import numpy as np
import matplotlib.pyplot as plt
img = np.zeros((100, 100, 3), dtype=np.uint8)
# Mostrar la imagen
plt.imshow(img)
plt.show()

Gradiente en blanco y negro

En este ejemplo se genera una imagen de 200x200 píxeles donde cada fila tiene un valor creciente entre 0 y 255. El resultado es un gradiente lineal en escala de grises.


import numpy as np
import matplotlib.pyplot as plt

# Tamaño de la imagen
w, h = 200, 200
img = np.zeros((h, w), dtype=np.uint8)

# Crear un gradiente lineal (0 a 255)
for i in range(h):
    img[i, :] = i

plt.imshow(img, cmap="gray")
plt.title("Gradiente en blanco y negro")
plt.show()
  

Patrón con seno y coseno

Usando funciones matemáticas como sin y cos, se pueden generar patrones visuales. Aquí se combinan ondas senoidales y cosenoidales para crear un efecto tipo "ondas de calor".


import numpy as np
import matplotlib.pyplot as plt

w, h = 300, 300
x = np.linspace(0, 4*np.pi, w)
y = np.linspace(0, 4*np.pi, h)
X, Y = np.meshgrid(x, y)

# Fórmula con seno y coseno
Z = np.sin(X) + np.cos(Y)

plt.imshow(Z, cmap="plasma")
plt.title("Patrón senoidal")
plt.colorbar()
plt.show()
  

Círculo en RGB

Aquí se crea un lienzo en negro de 300x300 píxeles. Con una máscara matemática se dibuja un círculo y se colorea en rojo (RGB: 255,0,0).


import numpy as np
import matplotlib.pyplot as plt

w, h = 300, 300
img = np.zeros((h, w, 3), dtype=np.uint8)

x = np.arange(w)
y = np.arange(h)
X, Y = np.meshgrid(x, y)

# Centro
cx, cy = w//2, h//2
r = 100

# Máscara del círculo
mask = (X-cx)**2 + (Y-cy)**2 < r**2

# Colorear el círculo de rojo
img[mask] = [255, 0, 0]

plt.imshow(img)
plt.title("Círculo Rojo")
plt.show()
  

Interferencia (patrón tipo Moiré)

Combinando ondas senoidales en 2D se pueden generar patrones de interferencia conocidos como moiré. Son muy usados en arte digital y simulaciones físicas.


import numpy as np
import matplotlib.pyplot as plt

w, h = 300, 300
x = np.linspace(0, 10*np.pi, w)
y = np.linspace(0, 10*np.pi, h)
X, Y = np.meshgrid(x, y)

# Fórmula de interferencia
Z = np.sin(X) * np.sin(Y)

plt.imshow(Z, cmap="inferno")
plt.title("Interferencia tipo Moiré")
plt.show()
  

Espiral logarítmica

Una espiral logarítmica se genera usando coordenadas polares. Este tipo de espirales aparece en la naturaleza (conchas, galaxias, flores). La intensidad depende del ángulo y la distancia al centro.


import numpy as np
import matplotlib.pyplot as plt

w, h = 400, 400
x = np.linspace(-2, 2, w)
y = np.linspace(-2, 2, h)
X, Y = np.meshgrid(x, y)

# Convertir a coordenadas polares
R = np.sqrt(X**2 + Y**2)
Theta = np.arctan2(Y, X)

# Fórmula de espiral
Z = np.sin(10 * np.log(R + 1e-5) + 5 * Theta)

plt.imshow(Z, cmap="twilight", extent=(-2,2,-2,2))
plt.title("Espiral logarítmica")
plt.show()
  

Fractal de Mandelbrot

El conjunto de Mandelbrot es uno de los fractales más famosos. Se genera iterando la fórmula z = z^2 + c en el plano complejo y coloreando según el número de iteraciones antes de divergir.


import numpy as np
import matplotlib.pyplot as plt

w, h = 500, 500
max_iter = 100

# Rango del plano complejo
x = np.linspace(-2, 1, w)
y = np.linspace(-1.5, 1.5, h)
X, Y = np.meshgrid(x, y)
C = X + 1j * Y
Z = np.zeros_like(C)
img = np.zeros(C.shape, dtype=int)

for i in range(max_iter):
    mask = np.abs(Z) <= 2
    Z[mask] = Z[mask]**2 + C[mask]
    img[mask] = i

plt.imshow(img, cmap="hot", extent=(-2,1,-1.5,1.5))
plt.title("Fractal de Mandelbrot")
plt.show()
  

Fractal de Julia

Similar al conjunto de Mandelbrot, el fractal de Julia se genera iterando z = z^2 + c pero con un valor fijo de c. Dependiendo del valor de c, se obtienen diferentes figuras.


import numpy as np
import matplotlib.pyplot as plt

w, h = 500, 500
max_iter = 200
c = complex(-0.7, 0.27015)

x = np.linspace(-1.5, 1.5, w)
y = np.linspace(-1.5, 1.5, h)
X, Y = np.meshgrid(x, y)
Z = X + 1j * Y

img = np.zeros(Z.shape, dtype=int)

for i in range(max_iter):
    mask = np.abs(Z) <= 2
    Z[mask] = Z[mask]**2 + c
    img[mask] = i

plt.imshow(img, cmap="inferno", extent=(-1.5,1.5,-1.5,1.5))
plt.title("Fractal de Julia")
plt.show()
  

Ruido Perlin (simulado)

El ruido Perlin es usado en gráficos por computadora para generar texturas naturales (nubes, fuego, terreno). Aquí se simula con sumas de ondas senoidales.


import numpy as np
import matplotlib.pyplot as plt

w, h = 400, 400
x = np.linspace(0, 5*np.pi, w)
y = np.linspace(0, 5*np.pi, h)
X, Y = np.meshgrid(x, y)

# Simulación de ruido con senos y cosenos
Z = (np.sin(X) + np.cos(Y) + np.sin(X+Y) + np.cos(X-Y))

plt.imshow(Z, cmap="terrain")
plt.title("Ruido Perlin simulado")
plt.show()
  

Espacios de color: RGB

El espacio RGB representa los colores mediante combinaciones de rojo, verde y azul.

from PIL import Image
import matplotlib.pyplot as plt
img = Image.open("foto.jpg")
r, g, b = img.split()
plt.imshow(r)
plt.show()

Espacios de color: Grayscale

Escala de grises elimina la información de color, dejando solo la intensidad.

from PIL import Image
gray = Image.open("foto.jpg").convert("L")
import matplotlib.pyplot as plt
plt.imshow(gray, cmap='gray')
plt.show()
            

Espacios de color: HSV

HSV separa la tonalidad (H), saturación (S) y valor (V).

import cv2
img = cv2.imread("foto.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
import matplotlib.pyplot as plt
plt.imshow(img)
plt.show()

Operaciones básicas: Redimensionar

Redimensionar cambia el tamaño de la imagen.

from PIL import Image
img = Image.open("foto.jpg")
resized = img.resize((200, 200))
import matplotlib.pyplot as plt
plt.imshow(resized)
plt.show()

Operaciones básicas: Recortar

Recortar selecciona una región de interés.

box = (50, 50, 150, 150)
cropped = img.crop(box)
import matplotlib.pyplot as plt
plt.imshow(cropped)
plt.show()

Operaciones básicas: Normalizar

Normalizar escala los valores de píxel, útil para modelos de IA.

import numpy as np
img_array = np.array(img) / 255.0
import matplotlib.pyplot as plt
plt.imshow(img_array)
plt.show()

Librerías: PIL (Pillow)

Pillow facilita tareas básicas de procesamiento de imágenes.

from PIL import Image, ImageFilter
img = Image.open("foto.jpg")
blurred = img.filter(ImageFilter.BLUR)
import matplotlib.pyplot as plt
plt.imshow(blurred)
plt.show()

Librerías: OpenCV

OpenCV es potente para visión por computador en tiempo real.

import cv2
img = cv2.imread("foto.jpg")
edges = cv2.Canny(img, 100, 200)
import matplotlib.pyplot as plt
plt.imshow(edges)
plt.show()

Librerías: TensorFlow Image

TensorFlow tiene herramientas para preprocesamiento eficiente.

import tensorflow as tf
img = tf.io.read_file("foto.jpg")
img = tf.image.decode_jpeg(img, channels=3)
img = tf.image.resize(img, [224, 224])
img = img / 255.0
import matplotlib.pyplot as plt
plt.imshow(img)
plt.show()