Spaces:
Runtime error
Runtime error
| """ | |
| 🎭 Face Editor PRO - Professional Edition | |
| Editor facial profissional com processamento avançado de imagem | |
| Autor: Daniel251 | |
| Versão: 2.0.1 PRO | |
| Data: 2026 | |
| """ | |
| import gradio as gr | |
| from PIL import Image, ImageDraw, ImageFilter, ImageEnhance, ImageOps, ImageChops | |
| import numpy as np | |
| import sys | |
| import os | |
| import math | |
| import warnings | |
| warnings.filterwarnings('ignore') | |
| print("=" * 80) | |
| print("🎨 FACE EDITOR PRO - PROFESSIONAL EDITION") | |
| print("=" * 80) | |
| # ========== IMPORTAÇÕES COM TRATAMENTO DE ERRO ========== | |
| cv2 = None | |
| try: | |
| import cv2 | |
| print("✅ OpenCV carregado:", cv2.__version__) | |
| except Exception as e: | |
| print(f"⚠️ OpenCV não disponível: {e}") | |
| skimage = None | |
| try: | |
| from skimage import filters, exposure, transform | |
| from skimage.restoration import denoise_bilateral, denoise_tv_chambolle | |
| from skimage.morphology import disk, erosion, dilation | |
| import skimage | |
| print("✅ scikit-image carregado:", skimage.__version__) | |
| except Exception as e: | |
| print(f"⚠️ scikit-image não disponível: {e}") | |
| scipy = None | |
| try: | |
| from scipy import ndimage | |
| from scipy.interpolate import interp1d | |
| import scipy | |
| print("✅ SciPy carregado:", scipy.__version__) | |
| except Exception as e: | |
| print(f"⚠️ SciPy não disponível: {e}") | |
| print("=" * 80) | |
| # ========== CONFIGURAÇÕES ========== | |
| MAX_IMAGE_SIZE = 2048 # Maior resolução | |
| IS_HUGGINGFACE = os.getenv('SPACE_ID') is not None | |
| # ========== FUNÇÕES AUXILIARES ========== | |
| def resize_image(image, max_size=MAX_IMAGE_SIZE): | |
| """Redimensiona mantendo qualidade""" | |
| if image is None: | |
| return None | |
| width, height = image.size | |
| if max(width, height) > max_size: | |
| ratio = max_size / max(width, height) | |
| new_size = (int(width * ratio), int(height * ratio)) | |
| return image.resize(new_size, Image.Resampling.LANCZOS) | |
| return image | |
| def pil_to_numpy(image): | |
| """Converte PIL para numpy array RGB""" | |
| return np.array(image).astype(np.float32) / 255.0 | |
| def numpy_to_pil(array): | |
| """Converte numpy array para PIL""" | |
| array = np.clip(array * 255, 0, 255).astype(np.uint8) | |
| return Image.fromarray(array) | |
| def detect_skin_mask(image): | |
| """Detecta região de pele usando cor""" | |
| img_array = pil_to_numpy(image) | |
| # Converter para HSV | |
| if cv2 is not None: | |
| hsv = cv2.cvtColor((img_array * 255).astype(np.uint8), cv2.COLOR_RGB2HSV) | |
| # Faixa de cor de pele em HSV | |
| lower_skin = np.array([0, 20, 70], dtype=np.uint8) | |
| upper_skin = np.array([20, 255, 255], dtype=np.uint8) | |
| mask1 = cv2.inRange(hsv, lower_skin, upper_skin) | |
| lower_skin2 = np.array([160, 20, 70], dtype=np.uint8) | |
| upper_skin2 = np.array([180, 255, 255], dtype=np.uint8) | |
| mask2 = cv2.inRange(hsv, lower_skin2, upper_skin2) | |
| mask = cv2.bitwise_or(mask1, mask2) | |
| # Suavizar máscara | |
| mask = cv2.GaussianBlur(mask, (15, 15), 0) | |
| mask = mask.astype(np.float32) / 255.0 | |
| return mask | |
| else: | |
| # Fallback simples baseado em RGB | |
| r, g, b = img_array[:,:,0], img_array[:,:,1], img_array[:,:,2] | |
| mask = ((r > 0.4) & (g > 0.2) & (b > 0.1) & | |
| (r > b) & (r > g) & | |
| (abs(r - g) > 0.1)).astype(np.float32) | |
| return mask | |
| # ========== FILTROS PROFISSIONAIS ========== | |
| def professional_smooth_skin(image, intensity=50): | |
| """Suavização de pele profissional com preservação de detalhes""" | |
| print(f"🎨 Suavização Profissional (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| img_array = pil_to_numpy(image) | |
| # Detectar máscara de pele | |
| skin_mask = detect_skin_mask(image) | |
| skin_mask_3d = np.stack([skin_mask]*3, axis=-1) | |
| # Aplicar bilateral filter (preserva bordas) | |
| if skimage is not None: | |
| smoothed = denoise_bilateral( | |
| img_array, | |
| sigma_color=0.05 * intensity_factor, | |
| sigma_spatial=15 * intensity_factor, | |
| channel_axis=-1 | |
| ) | |
| elif cv2 is not None: | |
| smoothed = cv2.bilateralFilter( | |
| (img_array * 255).astype(np.uint8), | |
| int(9 * intensity_factor), | |
| 75 * intensity_factor, | |
| 75 * intensity_factor | |
| ).astype(np.float32) / 255.0 | |
| else: | |
| # Fallback: Gaussian blur | |
| pil_img = numpy_to_pil(img_array) | |
| smoothed = pil_to_numpy(pil_img.filter( | |
| ImageFilter.GaussianBlur(radius=5 * intensity_factor) | |
| )) | |
| # Aplicar apenas em áreas de pele | |
| result = img_array * (1 - skin_mask_3d * intensity_factor) + \ | |
| smoothed * (skin_mask_3d * intensity_factor) | |
| return numpy_to_pil(result) | |
| def advanced_brighten_face(image, intensity=50): | |
| """Iluminação facial avançada com equilíbrio de tons""" | |
| print(f"💡 Iluminação Avançada (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| img_array = pil_to_numpy(image) | |
| # Detectar pele | |
| skin_mask = detect_skin_mask(image) | |
| skin_mask_3d = np.stack([skin_mask]*3, axis=-1) | |
| # Ajustar gamma para clarear | |
| gamma = 1.0 + (0.5 * intensity_factor) | |
| brightened = np.power(img_array, 1.0/gamma) | |
| # Adicionar leve saturação | |
| pil_brightened = numpy_to_pil(brightened) | |
| enhancer = ImageEnhance.Color(pil_brightened) | |
| saturated = pil_to_numpy(enhancer.enhance(1.0 + 0.1 * intensity_factor)) | |
| # Aplicar apenas em pele | |
| result = img_array * (1 - skin_mask_3d * intensity_factor) + \ | |
| saturated * (skin_mask_3d * intensity_factor) | |
| return numpy_to_pil(result) | |
| def professional_sharpen(image, intensity=50): | |
| """Nitidez profissional com unsharp mask""" | |
| print(f"✨ Nitidez Profissional (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| # Unsharp mask | |
| blurred = image.filter(ImageFilter.GaussianBlur(radius=2)) | |
| img_array = np.array(image).astype(np.float32) | |
| blur_array = np.array(blurred).astype(np.float32) | |
| # Calcular máscara | |
| unsharp_mask = img_array - blur_array | |
| # Aplicar nitidez | |
| sharpened = img_array + (unsharp_mask * intensity_factor * 2) | |
| sharpened = np.clip(sharpened, 0, 255).astype(np.uint8) | |
| return Image.fromarray(sharpened) | |
| def enhance_eyes_pro(image, intensity=50): | |
| """Realce de olhos profissional""" | |
| print(f"👁️ Realce de Olhos Pro (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| # Aumentar contraste local nos olhos | |
| img_array = pil_to_numpy(image) | |
| # Detectar regiões escuras (olhos tendem a ser mais escuros) | |
| gray = np.mean(img_array, axis=2) | |
| eye_mask = (gray < 0.4).astype(np.float32) | |
| # Suavizar máscara | |
| if cv2 is not None: | |
| eye_mask = cv2.GaussianBlur(eye_mask, (21, 21), 0) | |
| eye_mask_3d = np.stack([eye_mask]*3, axis=-1) | |
| # Aumentar saturação e brilho em áreas dos olhos | |
| pil_img = numpy_to_pil(img_array) | |
| # Saturação | |
| enhancer = ImageEnhance.Color(pil_img) | |
| saturated = pil_to_numpy(enhancer.enhance(1.0 + 0.5 * intensity_factor)) | |
| # Contraste | |
| pil_temp = numpy_to_pil(saturated) | |
| enhancer = ImageEnhance.Contrast(pil_temp) | |
| contrasted = pil_to_numpy(enhancer.enhance(1.0 + 0.3 * intensity_factor)) | |
| # Aplicar máscara | |
| result = img_array * (1 - eye_mask_3d * intensity_factor * 0.7) + \ | |
| contrasted * (eye_mask_3d * intensity_factor * 0.7) | |
| return numpy_to_pil(result) | |
| def whiten_teeth_pro(image, intensity=50): | |
| """Clareamento dental profissional""" | |
| print(f"🦷 Clareamento Dental Pro (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| img_array = pil_to_numpy(image) | |
| # Detectar região da boca (parte inferior central) | |
| height, width = img_array.shape[:2] | |
| mouth_region = img_array[int(height*0.6):int(height*0.85), | |
| int(width*0.3):int(width*0.7)] | |
| # Criar máscara para dentes (áreas claras na boca) | |
| gray_mouth = np.mean(mouth_region, axis=2) | |
| teeth_mask = (gray_mouth > 0.5).astype(np.float32) | |
| # Suavizar | |
| if cv2 is not None: | |
| teeth_mask = cv2.GaussianBlur(teeth_mask, (5, 5), 0) | |
| # Clarear dentes | |
| whitened_mouth = mouth_region.copy() | |
| for i in range(3): | |
| whitened_mouth[:,:,i] = np.clip( | |
| mouth_region[:,:,i] + (0.2 * intensity_factor * teeth_mask), | |
| 0, 1 | |
| ) | |
| # Aplicar de volta | |
| result = img_array.copy() | |
| result[int(height*0.6):int(height*0.85), | |
| int(width*0.3):int(width*0.7)] = \ | |
| mouth_region * (1 - np.stack([teeth_mask]*3, axis=-1) * intensity_factor) + \ | |
| whitened_mouth * (np.stack([teeth_mask]*3, axis=-1) * intensity_factor) | |
| return numpy_to_pil(result) | |
| def remove_blemishes(image, intensity=50): | |
| """Remoção de imperfeições""" | |
| print(f"✨ Remoção de Imperfeições (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| img_array = pil_to_numpy(image) | |
| # Detectar pele | |
| skin_mask = detect_skin_mask(image) | |
| # Aplicar median filter para remover pequenas imperfeições | |
| if cv2 is not None: | |
| cleaned = cv2.medianBlur( | |
| (img_array * 255).astype(np.uint8), | |
| 5 | |
| ).astype(np.float32) / 255.0 | |
| else: | |
| pil_img = numpy_to_pil(img_array) | |
| cleaned = pil_to_numpy(pil_img.filter(ImageFilter.MedianFilter(size=5))) | |
| # Aplicar bilateral para suavizar mantendo bordas | |
| if skimage is not None: | |
| cleaned = denoise_bilateral( | |
| cleaned, | |
| sigma_color=0.03 * intensity_factor, | |
| sigma_spatial=10, | |
| channel_axis=-1 | |
| ) | |
| skin_mask_3d = np.stack([skin_mask]*3, axis=-1) | |
| # Misturar apenas em pele | |
| result = img_array * (1 - skin_mask_3d * intensity_factor * 0.6) + \ | |
| cleaned * (skin_mask_3d * intensity_factor * 0.6) | |
| return numpy_to_pil(result) | |
| def color_correction(image, intensity=50): | |
| """Correção de cor profissional""" | |
| print(f"🎨 Correção de Cor (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| img_array = pil_to_numpy(image) | |
| # Balanceamento de brancos | |
| avg_r = np.mean(img_array[:,:,0]) | |
| avg_g = np.mean(img_array[:,:,1]) | |
| avg_b = np.mean(img_array[:,:,2]) | |
| avg_gray = (avg_r + avg_g + avg_b) / 3 | |
| # Ajustar canais | |
| corrected = img_array.copy() | |
| corrected[:,:,0] *= (1 + (avg_gray - avg_r) * intensity_factor * 0.5) | |
| corrected[:,:,1] *= (1 + (avg_gray - avg_g) * intensity_factor * 0.5) | |
| corrected[:,:,2] *= (1 + (avg_gray - avg_b) * intensity_factor * 0.5) | |
| corrected = np.clip(corrected, 0, 1) | |
| # Ajustar vibrance (saturação suave) | |
| pil_img = numpy_to_pil(corrected) | |
| enhancer = ImageEnhance.Color(pil_img) | |
| result = enhancer.enhance(1.0 + 0.2 * intensity_factor) | |
| return result | |
| def add_glow(image, intensity=50): | |
| """Adiciona brilho suave (glow effect)""" | |
| print(f"✨ Efeito Glow (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| # Criar versão borrada | |
| blurred = image.filter(ImageFilter.GaussianBlur(radius=20)) | |
| # Blend com imagem original | |
| return Image.blend(image, blurred, 0.3 * intensity_factor) | |
| def enhance_lips(image, intensity=50): | |
| """Realce labial profissional""" | |
| print(f"💄 Realce Labial (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| img_array = pil_to_numpy(image) | |
| # Detectar região da boca | |
| height, width = img_array.shape[:2] | |
| mouth_region = img_array[int(height*0.65):int(height*0.8), | |
| int(width*0.35):int(width*0.65)] | |
| # Detectar lábios (tons avermelhados) | |
| r, g, b = mouth_region[:,:,0], mouth_region[:,:,1], mouth_region[:,:,2] | |
| lip_mask = ((r > g * 1.1) & (r > b * 1.1)).astype(np.float32) | |
| # Suavizar máscara | |
| if cv2 is not None: | |
| lip_mask = cv2.GaussianBlur(lip_mask, (7, 7), 0) | |
| # Aumentar saturação e tom avermelhado | |
| enhanced_mouth = mouth_region.copy() | |
| enhanced_mouth[:,:,0] = np.clip( | |
| mouth_region[:,:,0] * (1 + 0.3 * intensity_factor * lip_mask), | |
| 0, 1 | |
| ) | |
| # Aplicar de volta | |
| result = img_array.copy() | |
| lip_mask_3d = np.stack([lip_mask]*3, axis=-1) | |
| result[int(height*0.65):int(height*0.8), | |
| int(width*0.35):int(width*0.65)] = \ | |
| mouth_region * (1 - lip_mask_3d * intensity_factor * 0.7) + \ | |
| enhanced_mouth * (lip_mask_3d * intensity_factor * 0.7) | |
| return numpy_to_pil(result) | |
| def adjust_contrast(image, intensity=50): | |
| """Ajuste de contraste inteligente""" | |
| print(f"⚡ Ajuste de Contraste (intensidade: {intensity})") | |
| # Mapear intensidade para -50 a +50 | |
| contrast_factor = (intensity - 50) / 50.0 | |
| contrast_value = 1.0 + (contrast_factor * 0.5) | |
| enhancer = ImageEnhance.Contrast(image) | |
| return enhancer.enhance(contrast_value) | |
| def adjust_saturation(image, intensity=50): | |
| """Ajuste de saturação""" | |
| print(f"🎨 Ajuste de Saturação (intensidade: {intensity})") | |
| # Mapear intensidade | |
| saturation_factor = intensity / 50.0 | |
| enhancer = ImageEnhance.Color(image) | |
| return enhancer.enhance(saturation_factor) | |
| def high_pass_filter(image, intensity=50): | |
| """Filtro High-Pass para detalhes""" | |
| print(f"🔍 Filtro High-Pass (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| # Criar versão borrada | |
| blurred = image.filter(ImageFilter.GaussianBlur(radius=10)) | |
| # Subtrair para obter detalhes | |
| img_array = np.array(image).astype(np.float32) | |
| blur_array = np.array(blurred).astype(np.float32) | |
| high_pass = img_array - blur_array + 128 | |
| high_pass = np.clip(high_pass, 0, 255) | |
| # Blend | |
| result = img_array * (1 - intensity_factor * 0.5) + \ | |
| high_pass * (intensity_factor * 0.5) | |
| return Image.fromarray(result.astype(np.uint8)) | |
| def professional_makeup(image, intensity=50): | |
| """Maquiagem profissional completa""" | |
| print(f"💅 Maquiagem Profissional Completa (intensidade: {intensity})") | |
| result = image | |
| result = professional_smooth_skin(result, intensity * 0.8) | |
| result = enhance_eyes_pro(result, intensity * 0.9) | |
| result = enhance_lips(result, intensity * 0.85) | |
| result = whiten_teeth_pro(result, intensity * 0.7) | |
| result = advanced_brighten_face(result, intensity * 0.6) | |
| result = color_correction(result, intensity * 0.5) | |
| return result | |
| def portrait_retouch(image, intensity=50): | |
| """Retoque de retrato profissional""" | |
| print(f"📸 Retoque de Retrato (intensidade: {intensity})") | |
| result = image | |
| result = remove_blemishes(result, intensity * 0.9) | |
| result = professional_smooth_skin(result, intensity * 0.7) | |
| result = professional_sharpen(result, intensity * 0.6) | |
| result = color_correction(result, intensity * 0.5) | |
| return result | |
| def instagram_filter(image, intensity=50): | |
| """Filtro estilo Instagram""" | |
| print(f"📱 Filtro Instagram (intensidade: {intensity})") | |
| intensity_factor = intensity / 100.0 | |
| result = image | |
| # Aumentar contraste | |
| enhancer = ImageEnhance.Contrast(result) | |
| result = enhancer.enhance(1.0 + 0.2 * intensity_factor) | |
| # Aumentar saturação | |
| enhancer = ImageEnhance.Color(result) | |
| result = enhancer.enhance(1.0 + 0.3 * intensity_factor) | |
| # Adicionar leve vinheta | |
| img_array = np.array(result).astype(np.float32) | |
| height, width = img_array.shape[:2] | |
| # Criar máscara de vinheta | |
| Y, X = np.ogrid[:height, :width] | |
| center_y, center_x = height / 2, width / 2 | |
| dist_from_center = np.sqrt((X - center_x)**2 + (Y - center_y)**2) | |
| max_dist = np.sqrt(center_x**2 + center_y**2) | |
| vignette = 1 - (dist_from_center / max_dist) ** 2 * 0.5 * intensity_factor | |
| vignette = np.clip(vignette, 0, 1) | |
| for i in range(3): | |
| img_array[:,:,i] *= vignette | |
| return Image.fromarray(img_array.astype(np.uint8)) | |
| # ========== MAPEAMENTO DE FILTROS ========== | |
| FILTERS = { | |
| "🎨 Maquiagem Profissional": professional_makeup, | |
| "📸 Retoque de Retrato": portrait_retouch, | |
| "💎 Pele Perfeita": professional_smooth_skin, | |
| "💡 Iluminação Facial": advanced_brighten_face, | |
| "✨ Nitidez Pro": professional_sharpen, | |
| "👁️ Realce de Olhos": enhance_eyes_pro, | |
| "🦷 Branquear Dentes": whiten_teeth_pro, | |
| "💄 Realçar Lábios": enhance_lips, | |
| "🔥 Remover Imperfeições": remove_blemishes, | |
| "🎨 Correção de Cor": color_correction, | |
| "✨ Efeito Glow": add_glow, | |
| "⚡ Contraste": adjust_contrast, | |
| "🌈 Saturação": adjust_saturation, | |
| "🔍 High-Pass": high_pass_filter, | |
| "📱 Filtro Instagram": instagram_filter, | |
| } | |
| # ========== PROCESSAMENTO PRINCIPAL ========== | |
| def process_image(image, filter_name, intensity): | |
| """Processa a imagem com filtro profissional""" | |
| try: | |
| if image is None: | |
| return None | |
| print("\n" + "=" * 80) | |
| print(f"🎨 PROCESSANDO: {filter_name}") | |
| print("=" * 80) | |
| # Redimensionar se necessário | |
| image = resize_image(image) | |
| # Aplicar filtro | |
| filter_func = FILTERS.get(filter_name) | |
| if filter_func: | |
| result = filter_func(image, intensity) | |
| else: | |
| result = image | |
| print("✅ Processamento concluído") | |
| print("=" * 80 + "\n") | |
| return result | |
| except Exception as e: | |
| print(f"❌ ERRO: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return image | |
| # ========== INTERFACE GRADIO ========== | |
| # Tema customizado | |
| custom_theme = gr.themes.Soft( | |
| primary_hue="purple", | |
| secondary_hue="pink", | |
| ).set( | |
| button_primary_background_fill="*primary_500", | |
| button_primary_background_fill_hover="*primary_600", | |
| ) | |
| with gr.Blocks(theme=custom_theme, title="🎭 Face Editor PRO", css=""" | |
| .gradio-container {max-width: 1400px !important;} | |
| .output-image {min-height: 400px;} | |
| footer {visibility: hidden;} | |
| """) as demo: | |
| gr.Markdown(""" | |
| # 🎨 Face Editor PRO - Professional Edition | |
| ### ✨ Editor Facial com Processamento Avançado de Imagem | |
| **Recursos Avançados:** | |
| - 💎 Suavização bilateral de pele com preservação de detalhes | |
| - 🎨 Correção de cor automática com balanceamento de brancos | |
| - 👁️ Realce inteligente de olhos com contraste adaptativo | |
| - 🦷 Clareamento dental profissional com detecção precisa | |
| - ✨ Remoção avançada de imperfeições usando median filtering | |
| - 📸 Retoque completo de retrato com múltiplas camadas | |
| - 💄 Maquiagem profissional com detecção facial | |
| - 🔍 Filtros high-pass e unsharp mask para nitidez perfeita | |
| **Status do Sistema:** | |
| """) | |
| # Status das bibliotecas | |
| status_html = f""" | |
| <div style="display: flex; gap: 20px; padding: 10px; background: rgba(255,255,255,0.1); border-radius: 10px; margin: 10px 0;"> | |
| <div style="flex: 1; text-align: center;"> | |
| <div style="font-size: 24px;">{"✅" if cv2 else "❌"}</div> | |
| <div><b>OpenCV</b></div> | |
| <div style="font-size: 12px; color: #888;">{cv2.__version__ if cv2 else "Indisponível"}</div> | |
| </div> | |
| <div style="flex: 1; text-align: center;"> | |
| <div style="font-size: 24px;">{"✅" if skimage else "❌"}</div> | |
| <div><b>scikit-image</b></div> | |
| <div style="font-size: 12px; color: #888;">{skimage.__version__ if skimage else "Indisponível"}</div> | |
| </div> | |
| <div style="flex: 1; text-align: center;"> | |
| <div style="font-size: 24px;">{"✅" if scipy else "❌"}</div> | |
| <div><b>SciPy</b></div> | |
| <div style="font-size: 12px; color: #888;">{scipy.__version__ if scipy else "Indisponível"}</div> | |
| </div> | |
| </div> | |
| """ | |
| gr.HTML(status_html) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| input_image = gr.Image( | |
| label="📸 Imagem Original", | |
| type="pil", | |
| height=400 | |
| ) | |
| with gr.Group(): | |
| filter_dropdown = gr.Dropdown( | |
| choices=list(FILTERS.keys()), | |
| value="🎨 Maquiagem Profissional", | |
| label="🎨 Selecione o Filtro Profissional", | |
| info="Escolha o efeito desejado" | |
| ) | |
| intensity_slider = gr.Slider( | |
| minimum=0, | |
| maximum=100, | |
| value=50, | |
| step=1, | |
| label="⚡ Intensidade do Efeito (%)", | |
| info="0 = Sem efeito | 100 = Efeito máximo" | |
| ) | |
| with gr.Row(): | |
| clear_btn = gr.ClearButton( | |
| components=[input_image], | |
| value="🗑️ Limpar", | |
| variant="secondary" | |
| ) | |
| process_btn = gr.Button( | |
| "🎨 Processar Imagem", | |
| variant="primary", | |
| size="lg" | |
| ) | |
| with gr.Column(scale=1): | |
| output_image = gr.Image( | |
| label="✨ Resultado Profissional", | |
| elem_classes=["output-image"], | |
| height=400 | |
| ) | |
| with gr.Row(): | |
| download_btn = gr.Button( | |
| "💾 Baixar Resultado", | |
| variant="secondary", | |
| size="sm" | |
| ) | |
| with gr.Accordion("📋 Guia de Filtros", open=False): | |
| gr.Markdown(""" | |
| ### 🎨 Maquiagem & Beleza | |
| - **🎨 Maquiagem Profissional**: Suite completa de maquiagem aplicando múltiplos filtros em sequência | |
| - **📸 Retoque de Retrato**: Retoque profissional completo com limpeza, suavização e correção | |
| - **💎 Pele Perfeita**: Suavização bilateral avançada que preserva bordas importantes | |
| - **🔥 Remover Imperfeições**: Limpeza de pele profissional usando median e bilateral filtering | |
| ### 💡 Iluminação & Cor | |
| - **💡 Iluminação Facial**: Ajuste de gamma e exposição com foco em tons de pele | |
| - **🎨 Correção de Cor**: Balanceamento automático de cor e ajuste de white balance | |
| - **⚡ Contraste**: Ajuste de contraste inteligente sem perder detalhes | |
| - **🌈 Saturação**: Controle de vibrance e saturação com proteção de tons de pele | |
| ### ✨ Detalhes & Realces | |
| - **✨ Nitidez Pro**: Unsharp mask profissional para nitidez natural | |
| - **👁️ Realce de Olhos**: Contraste e saturação focados na região dos olhos | |
| - **🦷 Branquear Dentes**: Clareamento dental preciso com detecção automática | |
| - **💄 Realçar Lábios**: Realce de cor labial com detecção de tons avermelhados | |
| ### 🌟 Efeitos Especiais | |
| - **✨ Efeito Glow**: Brilho suave e etéreo para look dreamy | |
| - **🔍 High-Pass**: Filtro de detalhes finos para nitidez extrema | |
| - **📱 Filtro Instagram**: Efeito estilo redes sociais com vinheta e saturação | |
| ### 💡 Dicas de Uso | |
| 1. **Comece com intensidade média (50%)** e ajuste conforme necessário | |
| 2. **Use filtros compostos** (Maquiagem Profissional, Retoque de Retrato) para resultados rápidos | |
| 3. **Combine filtros**: Processe a imagem múltiplas vezes com filtros diferentes | |
| 4. **Para selfies**: Maquiagem Profissional ou Retoque de Retrato funcionam melhor | |
| 5. **Para fotos artísticas**: Experimente High-Pass e Filtro Instagram | |
| """) | |
| with gr.Accordion("ℹ️ Sobre o Sistema", open=False): | |
| gr.Markdown(""" | |
| ### 🔧 Tecnologias Utilizadas | |
| - **OpenCV**: Processamento de imagem em tempo real e detecção de cores | |
| - **scikit-image**: Filtros avançados como bilateral denoising | |
| - **SciPy**: Interpolação e processamento científico de imagens | |
| - **PIL/Pillow**: Manipulação básica de imagens | |
| - **NumPy**: Operações matriciais de alta performance | |
| ### 🎯 Algoritmos Implementados | |
| - Bilateral Filtering (preservação de bordas) | |
| - Unsharp Masking (nitidez profissional) | |
| - Color Space Conversion (RGB → HSV) | |
| - Gamma Correction (ajuste de exposição) | |
| - Median Filtering (remoção de ruído) | |
| - Gaussian Blur (suavização controlada) | |
| - High-Pass Filtering (extração de detalhes) | |
| ### 📊 Limites do Sistema | |
| - Resolução máxima: 2048px (maior dimensão) | |
| - Formatos suportados: JPG, PNG, WEBP | |
| - Processamento otimizado para Hugging Face Spaces | |
| ### 👨💻 Desenvolvido por | |
| **Daniel251** - Face Editor PRO v2.0.1 | |
| """) | |
| # Event handlers | |
| process_btn.click( | |
| fn=process_image, | |
| inputs=[input_image, filter_dropdown, intensity_slider], | |
| outputs=output_image, | |
| api_name="process" | |
| ) | |
| # Atalho: Enter no slider também processa | |
| intensity_slider.release( | |
| fn=process_image, | |
| inputs=[input_image, filter_dropdown, intensity_slider], | |
| outputs=output_image | |
| ) | |
| if __name__ == "__main__": | |
| print("\n" + "=" * 80) | |
| print("🚀 INICIANDO FACE EDITOR PRO") | |
| print("=" * 80 + "\n") | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| show_error=True | |
| ) |