File size: 6,989 Bytes
99c36ed
 
 
 
0b1ff79
 
 
 
 
2283654
0b1ff79
2283654
0b1ff79
2283654
 
0b1ff79
 
99c36ed
2283654
 
 
 
 
 
 
 
 
 
 
 
 
f91e75b
 
 
 
 
 
 
 
 
 
2283654
f91e75b
99c36ed
f91e75b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0b1ff79
2283654
99c36ed
2283654
 
f91e75b
 
 
 
0b1ff79
99c36ed
2283654
0b1ff79
 
f91e75b
 
2283654
 
 
99c36ed
 
2283654
 
 
0b1ff79
2283654
0b1ff79
2283654
f91e75b
2283654
 
 
 
0b1ff79
2283654
 
 
 
 
f91e75b
 
2283654
 
 
 
 
 
f91e75b
 
 
0b1ff79
 
2283654
99c36ed
f91e75b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import gradio as gr
from deepface import DeepFace
import numpy as np
from PIL import Image
from diffusers import StableDiffusionPipeline
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

# Detectar si hay GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Cargar modelo de difusión especializado en fantasía (modelo público)
pipe = StableDiffusionPipeline.from_pretrained(
    "nitrosocke/Arcane-Diffusion",  # o el que prefieras
    torch_dtype=torch.float16 if device.type == "cuda" else torch.float32
)
pipe = pipe.to(device)

# Modelo GPT-Neo para enriquecer la descripción
model_name = "EleutherAI/gpt-neo-1.3B"
model = AutoModelForCausalLM.from_pretrained(model_name).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# Función para recortar el prompt a 77 tokens
def recortar_prompt(prompt, max_tokens=77):
    tokens = tokenizer(prompt, return_tensors="pt")["input_ids"]
    if len(tokens[0]) > max_tokens:
        tokens = tokens[0][:max_tokens]
        prompt = tokenizer.decode(tokens, skip_special_tokens=True)
    return prompt

# Mapeo de emociones
emociones = {
    "happy": "feliz",
    "sad": "triste",
    "angry": "enojado",
    "surprise": "sorprendido",
    "fear": "miedo",
    "disgust": "asqueroso",
    "neutral": "neutral"
}
# Analizar rostro
# Función para analizar rostro
def analizar_rostro(image):
    try:
        image_np = np.array(image)
        result = DeepFace.analyze(image_np, actions=["age", "gender", "emotion", "race"], enforce_detection=False)

        if isinstance(result, list):
            result = result[0]

        # Obtener los resultados
        gender = result.get('gender', {})
        gender_text = "una mujer" if gender.get('Woman', 0) > gender.get('Man', 0) else "un hombre"

        # Mapeo de razas
        raza = {
            "white": "de piel blanca",
            "black": "de piel negra",
            "asian": "asiático",
            "indian": "de piel india",
            "middle eastern": "de origen medio oriental",
            "latino hispanic": "latino/hispano"
        }
        color_piel = raza.get(result.get('dominant_race', '').lower(), "de piel desconocida")

        # Mapeo de emociones
        emotion = result.get('dominant_emotion', '').lower()
        emocion_text = emociones.get(emotion, "sin emoción destacada")

        # Detectar color de ojos y cabello
        color_ojos = "con ojos marrones" if emotion != "blue" else "con ojos azules"
        color_pelo = "y pelo castaño" if result.get('dominant_race', '').lower() != "blond" else "y pelo rubio"

        # Crear la descripción
        descripcion = (
            f"Una persona {color_piel}, {color_ojos} {color_pelo}, de aproximadamente {result.get('age', 'una edad desconocida')} años, "
            f"que parece estar {emocion_text}. Esta persona es {gender_text}."
        )
        return descripcion
    except Exception as e:
        return f"Error al analizar la imagen: {str(e)}"

# Generar descripción de fantasía
def generar_fantasia(descripcion_literal):
    prompt_base = (
        f"{descripcion_literal} Lleva una capa mágica que cambia de color con la luz, y su ropa está adornada con gemas brillantes. "
        "Está en un mundo fantástico con castillos flotantes, cielos con auroras mágicas y un bosque encantado donde los árboles susurran secretos. "
        "En su camino, encuentra criaturas místicas, fortalezas misteriosas y secretos antiguos que desafían su valentía. "
        "Tiene una misión que podría alterar el destino del reino. "
        "A su lado, una criatura mágica que tiene la habilidad de cambiar de forma."
    )

    inputs = tokenizer(prompt_base, return_tensors="pt").to(device)
    outputs = model.generate(
        **inputs,
        max_new_tokens=150,  # Aumentar el número de tokens generados
        temperature=1.2,  # Aumentar la temperatura para mayor creatividad
        no_repeat_ngram_size=2,
        top_p=0.9,
        top_k=50
    )

    generated = tokenizer.decode(outputs[0], skip_special_tokens=True)
    if generated.startswith(prompt_base):
        generated = generated[len(prompt_base):].strip()

    return prompt_base + " " + generated

# Generar imagen con prompt mejorado y negative prompt
def generar_imagen_fantasia(descripcion_fantasia, progress=gr.Progress()):
    descripcion_fantasia_recortada = recortar_prompt(descripcion_fantasia)
    prompt_visual = (
        f"{descripcion_fantasia_recortada}. Fantasy portrait, glowing magical cloak, enchanted gems, floating castles, magical auroras in the sky, enchanted forest, cinematic lighting, fantasy art style, 8k"
    )

    descripcion_fantasia_recortada = recortar_prompt(prompt_visual)

    # Mostrar por pantalla el prompt que se utiliza para generar la imagen
    print("Prompt para generar la imagen:", descripcion_fantasia_recortada)

    # Empezar la barra de progreso
    progress(0.1)
    image = pipe(
        descripcion_fantasia_recortada,
        negative_prompt="modern clothing, blurry, low quality, photo style, watermark, nsfw, ugly, bad anatomy, disfigured, deformed, extra limbs, close up, out of frame, mutation, mutated, ugly, poorly drawn face, mutation",
        num_inference_steps=50,
        guidance_scale=7.5,
    ).images[0]

    # Completar la barra de progreso
    progress(1.0)
    return image

# Interfaz Gradio
with gr.Blocks() as demo:
    gr.Markdown("# 🌟 **Generador de Personaje de Fantasía** 🌟")
    
    with gr.Tabs():
        with gr.TabItem("1. Subir Imagen y Análisis Facial"):
            gr.Markdown("### 1. Sube una imagen para transformarte en un ser mágico")
            gr.Markdown("Puedes probar arrastrando una imagen de [https://thispersondoesnotexist.com/](https://thispersondoesnotexist.com/).")
            image_input = gr.Image(type="pil", label="Imagen de entrada")
            descripcion_output = gr.Textbox(label="Descripción literal automática (con DeepFace)", interactive=True)

            image_input.change(analizar_rostro, inputs=image_input, outputs=descripcion_output)

        with gr.TabItem("2. Generar Descripción de Fantasía"):
            gr.Markdown("### 2. Descripción de Fantasía (con EleutherAI/gpt-neo-1.3B)")
            boton_fantasia = gr.Button("✨ Generar descripción de fantasía")
            descripcion_fantasia_output = gr.Textbox(label="Descripción de fantasía", interactive=False)

            boton_fantasia.click(generar_fantasia, inputs=descripcion_output, outputs=descripcion_fantasia_output)

        with gr.TabItem("3. Generar Imagen"):
            gr.Markdown("### 3. Generar imagen de fantasía")
            boton_imagen = gr.Button("🎨 Generar imagen de fantasía (con nitrosocke/Arcane-Diffusion)")
            output_image = gr.Image(label="Imagen de fantasía generada")

            boton_imagen.click(generar_imagen_fantasia, inputs=descripcion_fantasia_output, outputs=output_image)
demo.launch()