===== Célula 2: Importações e carregamento do modelo de IA =====
import gradio as gr
import numpy as np
import cv2
from PIL import Image
from simple_lama_inpainting import SimpleLama
print("Carregando modelo de IA (LaMa)... pode levar 1-2 minutos na primeira vez.")
lama = SimpleLama()
print("✅ Modelo carregado.")
===== Célula 3: Função principal de remoção =====
def extrair_mascara(editor_data):
"""
Extrai a máscara a partir do que o usuário pintou no ImageEditor.
editor_data é um dicionário com 'background' e 'layers' (camada de desenho).
"""
if editor_data is None or editor_data.get("layers") is None or len(editor_data["layers"]) == 0:
return None, None
background = editor_data["background"]
if background is None:
return None, None
bg_img = Image.fromarray(background).convert("RGB") if isinstance(background, np.ndarray) else background.convert("RGB")
# Combina todas as camadas pintadas em uma única máscara
layer = editor_data["layers"][0]
layer_np = np.array(layer)
# Pixels com qualquer opacidade/cor pintada viram máscara (canal alfa ou soma de cores)
if layer_np.shape[-1] == 4:
mask = (layer_np[:, :, 3] > 10).astype(np.uint8) * 255
else:
mask = (layer_np.sum(axis=-1) > 10).astype(np.uint8) * 255
return bg_img, mask
def pre_visualizar(editor_data):
bg_img, mask = extrair_mascara(editor_data)
if bg_img is None or mask is None or mask.sum() == 0:
return None, "⚠️ Pinte sobre a logo antes de pré-visualizar."
overlay = np.array(bg_img).copy()
overlay[mask > 0] = [255, 0, 0]
blended = cv2.addWeighted(np.array(bg_img), 0.6, overlay, 0.4, 0)
return Image.fromarray(blended), "✅ Área marcada em vermelho. Confira antes de confirmar a remoção."
def remover_logo(editor_data, margem, confirmar):
if not confirmar:
return None, "❌ Remoção não realizada — marque a confirmação para prosseguir."
bg_img, mask = extrair_mascara(editor_data)
if bg_img is None or mask is None or mask.sum() == 0:
return None, "⚠️ Nenhuma área pintada. Use o pincel para marcar a logo primeiro."
if margem > 0:
kernel = np.ones((int(margem), int(margem)), np.uint8)
mask = cv2.dilate(mask, kernel, iterations=1)
mask_img = Image.fromarray(mask)
# IA generativa reconstrói apenas a área pintada, respeitando o formato exato da logo
resultado = lama(bg_img, mask_img)
return resultado, "✅ Logo removida com sucesso, mantendo a área ao redor intacta."
def salvar_resultado(imagem_resultado):
if imagem_resultado is None:
return None
caminho = "imagem_sem_logo.png"
imagem_resultado.save(caminho)
return caminho
# ===== Célula 4: Interface HTML interativa com pincel (via Gradio) =====
with gr.Blocks(title="Remoção de Logo / Marca d'água") as app:
gr.Markdown(
"## 🧽 Remoção de Logo com IA\n"
"1. Envie a imagem.\n"
"2. Use o pincel para pintar exatamente sobre a logo (não precisa ser perfeito, dá pra errar um pouco pra fora).\n"
"3. Pré-visualize a área marcada.\n"
"4. Confirme e remova."
)
with gr.Row():
with gr.Column():
editor = gr.ImageEditor(
type="numpy",
label="Pinte sobre a logo com o pincel",
brush=gr.Brush(colors=["#FF0000"], default_size=20),
canvas_size=(800, 800),
)
margem = gr.Slider(0, 30, value=6, step=1, label="Margem extra (px) — cobre bordas semitransparentes")
btn_preview = gr.Button("👁️ Pré-visualizar área marcada")
preview_output = gr.Image(label="Área que será removida")
preview_status = gr.Textbox(label="Status da pré-visualização", interactive=False)
confirmar = gr.Checkbox(label="✅ Confirmo a área marcada e desejo remover a logo", value=False)
btn_remover = gr.Button("🧽 Remover logo", variant="primary")
with gr.Column():
resultado_output = gr.Image(label="Resultado final")
status_output = gr.Textbox(label="Status da remoção", interactive=False)
btn_baixar = gr.Button("⬇️ Preparar download")
arquivo_output = gr.File(label="Arquivo para download")
btn_preview.click(
pre_visualizar,
inputs=editor,
outputs=[preview_output, preview_status]
)
btn_remover.click(
remover_logo,
inputs=[editor, margem, confirmar],
outputs=[resultado_output, status_output]
)
btn_baixar.click(
salvar_resultado,
inputs=resultado_output,
outputs=arquivo_output
)
app.launch(share=False) # Important: set share=False for Hugging Face Spaces deployment