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() |