Spaces:
Sleeping
Sleeping
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() |