JustPaste
HomeCategoriesAboutDonateContactTerms of UsePrivacy Policy
JustPaste

Free online notepad — write and share instantly

Navigate

  • Home
  • Timeline
  • Categories

Info

  • About
  • Donate
  • Contact

Legal

  • Terms of Use
  • Privacy Policy

© 2026 JustPaste.app. All rights reserved.

Made with ♥ by JustPaste

Untitled Page | JustPaste.app
about 2 months ago1 views
👨‍💻Programming
import numpy as np
import cv2
import random

# =====================================================
# 1. Cargar imagen en escala de grises
# =====================================================
# imagen = "imagen1.png"
# imagen = "imagen2.jpeg"
imagen = "imagen3.png"

img = cv2.imread(imagen, 0)

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

# La normalizamos a [0,1]
img = img / 255.0


# =====================================================
# 2. Funcion sigmoide g(x)
# =====================================================
# alpha controla la pendiente
# delta controla el desplazamiento
def sigmoide(img, alpha, delta):
    g = 1.0 / (1.0 + np.exp(-alpha * (img - delta)))

    # Normalizamos el resultado otra vez a [0,1]
    g_min = g.min()
    g_max = g.max()

    if g_max - g_min == 0:
        return np.zeros_like(g)

    return (g - g_min) / (g_max - g_min)


# =====================================================
# 3. Medidas de calidad
# =====================================================
def entropia(img):
    img_u8 = (img * 255).astype(np.uint8)
    hist = cv2.calcHist([img_u8], [0], None, [256], [0, 256])
    p = hist / hist.sum()
    p = p[p > 0]
    return float(-np.sum(p * np.log2(p)))

def desviacion(img):
    return float(np.std(img))


# =====================================================
# 4. Funcion objetivo
# =====================================================
# Para mejorar contraste, aqui maximizamos:
# - entropia
# - desviacion estandar
def evaluar(ind, modelo):
    alpha, delta = ind
    img2 = sigmoide(img, alpha, delta)

    if modelo == "entropia":
        return entropia(img2)
    elif modelo == "desviacion":
        return desviacion(img2)
    else:
        raise ValueError("Modelo no valido")


# =====================================================
# 5. Crear individuo
# =====================================================
# Un individuo = [alpha, delta]
# alpha en [0,10]
# delta en [0,1]
def crear_individuo():
    alpha = random.uniform(0, 10)
    delta = random.uniform(0, 1)
    return [alpha, delta]


# =====================================================
# 6. Seleccion por torneo determinista binario
# =====================================================
# Se eligen 2 individuos al azar y gana el mejor
def torneo_binario(poblacion, fitness):
    i, j = random.sample(range(len(poblacion)), 2)

    if fitness[i] > fitness[j]:
        return poblacion[i][:]
    else:
        return poblacion[j][:]


# =====================================================
# 7. Cruzamiento SBX
# =====================================================
def sbx_variable(x1, x2, xmin, xmax, eta_c):
    # Si los valores son casi iguales, no tiene sentido cruzar
    if abs(x1 - x2) < 1e-14:
        return x1, x2

    # Aseguramos x1 < x2
    if x1 > x2:
        x1, x2 = x2, x1

    u = random.random()

    # Primer hijo
    beta = 1.0 + (2.0 * (x1 - xmin) / (x2 - x1))
    alpha = 2.0 - beta ** (-(eta_c + 1.0))

    if u <= 1.0 / alpha:
        beta_q = (u * alpha) ** (1.0 / (eta_c + 1.0))
    else:
        beta_q = (1.0 / (2.0 - u * alpha)) ** (1.0 / (eta_c + 1.0))

    h1 = 0.5 * ((x1 + x2) - beta_q * (x2 - x1))

    # Segundo hijo
    beta = 1.0 + (2.0 * (xmax - x2) / (x2 - x1))
    alpha = 2.0 - beta ** (-(eta_c + 1.0))

    if u <= 1.0 / alpha:
        beta_q = (u * alpha) ** (1.0 / (eta_c + 1.0))
    else:
        beta_q = (1.0 / (2.0 - u * alpha)) ** (1.0 / (eta_c + 1.0))

    h2 = 0.5 * ((x1 + x2) + beta_q * (x2 - x1))

    # Respetar limites
    h1 = min(max(h1, xmin), xmax)
    h2 = min(max(h2, xmin), xmax)

    return h1, h2


def cruza_sbx(p1, p2, pc=0.9, eta_c=15):
    # Con cierta probabilidad si hay cruce, si no se copian
    if random.random() > pc:
        return p1[:], p2[:]

    h1 = [0, 0]
    h2 = [0, 0]

    # alpha en [0,10]
    h1[0], h2[0] = sbx_variable(p1[0], p2[0], 0.0, 10.0, eta_c)

    # delta en [0,1]
    h1[1], h2[1] = sbx_variable(p1[1], p2[1], 0.0, 1.0, eta_c)

    return h1, h2


# =====================================================
# 8. Mutacion polinomial
# =====================================================
def mutacion_variable(x, xmin, xmax, eta_m):
    if xmin == xmax:
        return x

    delta1 = (x - xmin) / (xmax - xmin)
    delta2 = (xmax - x) / (xmax - xmin)
    u = random.random()
    mut_pow = 1.0 / (eta_m + 1.0)

    if u < 0.5:
        xy = 1.0 - delta1
        val = 2.0 * u + (1.0 - 2.0 * u) * (xy ** (eta_m + 1.0))
        delta_q = val ** mut_pow - 1.0
    else:
        xy = 1.0 - delta2
        val = 2.0 * (1.0 - u) + 2.0 * (u - 0.5) * (xy ** (eta_m + 1.0))
        delta_q = 1.0 - val ** mut_pow

    x_nuevo = x + delta_q * (xmax - xmin)
    x_nuevo = min(max(x_nuevo, xmin), xmax)

    return x_nuevo


def mutacion_polinomial(ind, pm=0.5, eta_m=20):
    hijo = ind[:]

    # Mutar alpha
    if random.random() < pm:
        hijo[0] = mutacion_variable(hijo[0], 0.0, 10.0, eta_m)

    # Mutar delta
    if random.random() < pm:
        hijo[1] = mutacion_variable(hijo[1], 0.0, 1.0, eta_m)

    return hijo


# =====================================================
# 9. Estadisticas de una poblacion
# =====================================================
def obtener_estadisticas(poblacion, fitness):
    pos_mejor = int(np.argmax(fitness))
    pos_peor = int(np.argmin(fitness))

    mejor = poblacion[pos_mejor]
    peor = poblacion[pos_peor]
    promedio = float(np.mean(fitness))

    return {
        "mejor_ind": mejor,
        "mejor_fit": float(fitness[pos_mejor]),
        "promedio": promedio,
        "peor_ind": peor,
        "peor_fit": float(fitness[pos_peor])
    }


# =====================================================
# 10. Algoritmo genetico
# =====================================================
# Sustitucion extintiva con elitismo:
# - se guarda el mejor de la poblacion actual
# - el resto desaparece
# - se reemplaza por hijos nuevos
def AG(modelo, pop_size=20, max_eval=100, elite=1, pc=0.9, pm=0.5, eta_c=15, eta_m=20):
    # Poblacion inicial
    poblacion = [crear_individuo() for _ in range(pop_size)]
    fitness = [evaluar(ind, modelo) for ind in poblacion]
    evaluaciones = pop_size

    while evaluaciones < max_eval:
        # 1. Guardar elite
        indices_ordenados = np.argsort(fitness)[::-1]
        elite_individuos = [poblacion[i][:] for i in indices_ordenados[:elite]]

        # 2. Crear nueva descendencia
        nueva_poblacion = []

        while len(nueva_poblacion) < pop_size - elite:
            # Seleccion de padres con torneo determinista binario
            padre1 = torneo_binario(poblacion, fitness)
            padre2 = torneo_binario(poblacion, fitness)

            # Cruzamiento
            hijo1, hijo2 = cruza_sbx(padre1, padre2, pc, eta_c)

            # Mutacion
            hijo1 = mutacion_polinomial(hijo1, pm, eta_m)
            hijo2 = mutacion_polinomial(hijo2, pm, eta_m)

            nueva_poblacion.append(hijo1)
            if len(nueva_poblacion) < pop_size - elite:
                nueva_poblacion.append(hijo2)

        # 3. Sustitucion extintiva con elitismo
        poblacion = elite_individuos + nueva_poblacion[:pop_size - elite]
        fitness = [evaluar(ind, modelo) for ind in poblacion]

        evaluaciones += (pop_size - elite)

    return obtener_estadisticas(poblacion, fitness)


# =====================================================
# 11. Imprimir tabla final
# =====================================================
def imprimir_tabla(resultados):
    print("\nResumen final")
    print("-" * 110)
    print(
        f"{'Modelo':<15}"
        f"{'Mejor alpha':>15}"
        f"{'Mejor delta':>15}"
        f"{'Mejor valor':>18}"
        f"{'Promedio':>18}"
        f"{'Peor alpha':>15}"
        f"{'Peor delta':>15}"
        f"{'Peor valor':>18}"
    )
    print("-" * 110)

    for modelo in resultados:
        r = resultados[modelo]

        print(
            f"{modelo:<15}"
            f"{r['mejor_ind'][0]:>15.6f}"
            f"{r['mejor_ind'][1]:>15.6f}"
            f"{r['mejor_fit']:>18.6f}"
            f"{r['promedio']:>18.6f}"
            f"{r['peor_ind'][0]:>15.6f}"
            f"{r['peor_ind'][1]:>15.6f}"
            f"{r['peor_fit']:>18.6f}"
        )

    print("-" * 110)


# =====================================================
# 12. Programa principal
# =====================================================
random.seed(42)
np.random.seed(42)

resultados = {}

for modelo in ["entropia", "desviacion"]:
    resumen = AG(
        modelo=modelo,
        pop_size=20,
        max_eval=100,
        elite=1,
        pc=0.9,
        pm=0.5,
        eta_c=15,
        eta_m=20
    )

    resultados[modelo] = resumen

    # Guardar imagen mejorada usando la mejor solucion encontrada
    mejor_alpha = resumen["mejor_ind"][0]
    mejor_delta = resumen["mejor_ind"][1]

    img_mejorada = sigmoide(img, mejor_alpha, mejor_delta)
    cv2.imwrite(f"{modelo}_{imagen}", (img_mejorada * 255).astype(np.uint8))

    print(f"\nModelo: {modelo}")
    print(f"Mejor solucion: alpha={mejor_alpha:.6f}, delta={mejor_delta:.6f}")
    print(f"Mejor valor: {resumen['mejor_fit']:.6f}")
    print(f"Promedio: {resumen['promedio']:.6f}")
    print(f"Peor solucion: alpha={resumen['peor_ind'][0]:.6f}, delta={resumen['peor_ind'][1]:.6f}")
    print(f"Peor valor: {resumen['peor_fit']:.6f}")

imprimir_tabla(resultados)
← Back to timeline