import cv2
import numpy as np
import os
import urllib.request

def download_sample_image():
    """Descarga una imagen de muestra si no existe una local."""
    img_name = 'sample_image.jpg'
    if not os.path.exists(img_name):
        print("Descargando imagen de muestra...")
        url = "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/sudoku.png"
        urllib.request.urlretrieve(url, img_name)
    return img_name

def apply_custom_filters(image_path, kernel_size):
    """
    Aplica 5 filtros de convolución a la imagen con el tamaño de kernel especificado.
    """
    # 1. Cargar imagen y convertir a escala de grises
    img = cv2.imread(image_path)
    if img is None:
        raise ValueError("No se pudo cargar la imagen")
    
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    k = kernel_size
    
    # Directorio de salida
    out_dir = f"resultados_k{k}"
    os.makedirs(out_dir, exist_ok=True)
    
    cv2.imwrite(os.path.join(out_dir, "0_original_gris.jpg"), gray_img)
    
    print(f"\n--- Generando Secuencia para Kernel {k}x{k} ---")

    # Filtro 1: Promedio (Blur)
    kernel_blur = np.ones((k, k), np.float32) / (k * k)
    res_blur = cv2.filter2D(gray_img, -1, kernel_blur)
    cv2.imwrite(os.path.join(out_dir, "1_blur.jpg"), res_blur)
    print("Filtro 1: Suavizado (Blur) aplicado.")

    # Filtro 2: Detección de Bordes (Laplaciano aproximado)
    kernel_edges = -np.ones((k, k), np.float32)
    kernel_edges[k//2, k//2] = (k * k) - 1
    res_edges = cv2.filter2D(gray_img, -1, kernel_edges)
    cv2.imwrite(os.path.join(out_dir, "2_bordes.jpg"), res_edges)
    print("Filtro 2: Detección de Bordes aplicado.")

    # Filtro 3: Enfoque (Sharpen)
    kernel_sharpen = -np.ones((k, k), np.float32)
    kernel_sharpen[k//2, k//2] = (k * k)
    res_sharpen = cv2.filter2D(gray_img, -1, kernel_sharpen)
    cv2.imwrite(os.path.join(out_dir, "3_enfoque.jpg"), res_sharpen)
    print("Filtro 3: Enfoque (Sharpen) aplicado.")

    # Filtro 4: Detección de Bordes Horizontales
    kernel_h = np.zeros((k, k), np.float32)
    for i in range(k//2):
        kernel_h[i, :] = -1
        kernel_h[k - 1 - i, :] = 1
    res_h = cv2.filter2D(gray_img, -1, kernel_h)
    cv2.imwrite(os.path.join(out_dir, "4_bordes_horizontales.jpg"), res_h)
    print("Filtro 4: Bordes Horizontales aplicado.")

    # Filtro 5: Relieve (Emboss)
    kernel_emboss = np.zeros((k, k), np.float32)
    kernel_emboss[0, 0] = -2
    kernel_emboss[k-1, k-1] = 2
    kernel_emboss[0, k-1] = -1
    kernel_emboss[k-1, 0] = 1
    kernel_emboss[k//2, k//2] = 1
    res_emboss = cv2.filter2D(gray_img, -1, kernel_emboss)
    cv2.imwrite(os.path.join(out_dir, "5_relieve.jpg"), res_emboss)
    print("Filtro 5: Relieve (Emboss) aplicado.")
    
    print(f"Secuencia {k}x{k} guardada en '{out_dir}/'")

if __name__ == "__main__":
    img_path = download_sample_image()
    
    # Generar secuencias para los 3 integrantes
    apply_custom_filters(img_path, kernel_size=3) # Secuencia Alexander
    apply_custom_filters(img_path, kernel_size=5) # Secuencia Neheman
    apply_custom_filters(img_path, kernel_size=7) # Secuencia William
    
    print("\n¡Proceso finalizado! Los pantallazos de las carpetas generadas servirán como evidencia para el foro.")
